From 1640fb105dad55a1d227d3978da1342fb8059ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Sat, 15 Mar 2025 14:15:35 +0100 Subject: [PATCH] new device: Lilygo T-Eth-Elite (#6321) --- src/DebugConfiguration.h | 9 +++- src/Power.cpp | 5 ++ src/gps/GPS.cpp | 6 ++- src/main.cpp | 4 +- src/mesh/InterfacesTemplates.cpp | 2 +- src/mesh/api/WiFiServerAPI.h | 5 ++ src/mesh/api/ethServerAPI.cpp | 2 +- src/mesh/api/ethServerAPI.h | 2 + src/mesh/http/WebServer.cpp | 9 +++- src/mesh/udp/UdpMulticastThread.h | 5 ++ src/mesh/wifi/WiFiAPClient.cpp | 48 +++++++++++++++-- src/mesh/wifi/WiFiAPClient.h | 12 ++++- src/modules/AdminModule.cpp | 2 +- src/mqtt/MQTT.cpp | 9 ++++ src/mqtt/MQTT.h | 2 +- src/platform/esp32/architecture.h | 2 + src/platform/esp32/main-esp32.cpp | 4 +- variants/t-eth-elite/pins_arduino.h | 26 +++++++++ variants/t-eth-elite/platformio.ini | 16 ++++++ variants/t-eth-elite/rfswitch.h | 11 ++++ variants/t-eth-elite/variant.h | 83 +++++++++++++++++++++++++++++ 21 files changed, 247 insertions(+), 17 deletions(-) create mode 100644 variants/t-eth-elite/pins_arduino.h create mode 100644 variants/t-eth-elite/platformio.ini create mode 100644 variants/t-eth-elite/rfswitch.h create mode 100644 variants/t-eth-elite/variant.h diff --git a/src/DebugConfiguration.h b/src/DebugConfiguration.h index 7987e7fa1..a34710eb0 100644 --- a/src/DebugConfiguration.h +++ b/src/DebugConfiguration.h @@ -121,10 +121,15 @@ extern "C" void logLegacy(const char *level, const char *fmt, ...); // Default Bluetooth PIN #define defaultBLEPin 123456 -#if HAS_ETHERNET +#if HAS_ETHERNET && !defined(USE_WS5500) #include #endif // HAS_ETHERNET +#if HAS_ETHERNET && defined(USE_WS5500) +#include +#define ETH ETH2 +#endif // HAS_ETHERNET + #if HAS_WIFI #include #endif // HAS_WIFI @@ -164,4 +169,4 @@ class Syslog bool vlogf(uint16_t pri, const char *appName, const char *fmt, va_list args) __attribute__((format(printf, 3, 0))); }; -#endif // HAS_ETHERNET || HAS_WIFI \ No newline at end of file +#endif // HAS_NETWORKING \ No newline at end of file diff --git a/src/Power.cpp b/src/Power.cpp index 8d5fe1c32..5768e9908 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -32,6 +32,11 @@ #include #endif +#if HAS_ETHERNET && defined(USE_WS5500) +#include +#define ETH ETH2 +#endif // HAS_ETHERNET + #endif #ifndef DELAY_FOREVER diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 7dcb77fcc..7f490ea3c 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1104,12 +1104,16 @@ int32_t GPS::runOnce() return (powerState == GPS_ACTIVE) ? GPS_THREAD_INTERVAL : 5000; } -// clear the GPS rx buffer as quickly as possible +// clear the GPS rx/tx buffer as quickly as possible void GPS::clearBuffer() { +#ifdef ARCH_ESP32 + _serial_gps->flush(false); +#else int x = _serial_gps->available(); while (x--) _serial_gps->read(); +#endif } /// Prepare the GPS for the cpu entering deep or light sleep, expect to be gone for at least 100s of msecs diff --git a/src/main.cpp b/src/main.cpp index 4634c7c14..797d911d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,12 +55,12 @@ NimbleBluetooth *nimbleBluetooth = nullptr; NRF52Bluetooth *nrf52Bluetooth = nullptr; #endif -#if HAS_WIFI +#if HAS_WIFI || defined(USE_WS5500) #include "mesh/api/WiFiServerAPI.h" #include "mesh/wifi/WiFiAPClient.h" #endif -#if HAS_ETHERNET +#if HAS_ETHERNET && !defined(USE_WS5500) #include "mesh/api/ethServerAPI.h" #include "mesh/eth/ethClient.h" #endif diff --git a/src/mesh/InterfacesTemplates.cpp b/src/mesh/InterfacesTemplates.cpp index 2720e8525..57abbf0ee 100644 --- a/src/mesh/InterfacesTemplates.cpp +++ b/src/mesh/InterfacesTemplates.cpp @@ -25,7 +25,7 @@ template class LR11x0Interface; template class SX126xInterface; #endif -#if HAS_ETHERNET +#if HAS_ETHERNET && !defined(USE_WS5500) #include "api/ethServerAPI.h" template class ServerAPI; template class APIServerPort; diff --git a/src/mesh/api/WiFiServerAPI.h b/src/mesh/api/WiFiServerAPI.h index 6e60bb678..5f2019983 100644 --- a/src/mesh/api/WiFiServerAPI.h +++ b/src/mesh/api/WiFiServerAPI.h @@ -3,6 +3,11 @@ #include "ServerAPI.h" #include +#if HAS_ETHERNET && defined(USE_WS5500) +#include +#define ETH ETH2 +#endif // HAS_ETHERNET + /** * Provides both debug printing and, if the client starts sending protobufs to us, switches to send/receive protobufs * (and starts dropping debug printing - FIXME, eventually those prints should be encapsulated in protobufs). diff --git a/src/mesh/api/ethServerAPI.cpp b/src/mesh/api/ethServerAPI.cpp index a8701848a..0ccf92df7 100644 --- a/src/mesh/api/ethServerAPI.cpp +++ b/src/mesh/api/ethServerAPI.cpp @@ -1,7 +1,7 @@ #include "configuration.h" #include -#if HAS_ETHERNET +#if HAS_ETHERNET && !defined(USE_WS5500) #include "ethServerAPI.h" diff --git a/src/mesh/api/ethServerAPI.h b/src/mesh/api/ethServerAPI.h index 9d25a2fc1..c616c87be 100644 --- a/src/mesh/api/ethServerAPI.h +++ b/src/mesh/api/ethServerAPI.h @@ -1,6 +1,7 @@ #pragma once #include "ServerAPI.h" +#ifndef USE_WS5500 #include /** @@ -23,3 +24,4 @@ class ethServerPort : public APIServerPort }; void initApiServer(int port = SERVER_API_DEFAULT_PORT); +#endif diff --git a/src/mesh/http/WebServer.cpp b/src/mesh/http/WebServer.cpp index d9856e157..5f6ad9eb3 100644 --- a/src/mesh/http/WebServer.cpp +++ b/src/mesh/http/WebServer.cpp @@ -12,6 +12,11 @@ #include #include +#if HAS_ETHERNET && defined(USE_WS5500) +#include +#define ETH ETH2 +#endif // HAS_ETHERNET + #ifdef ARCH_ESP32 #include "esp_task_wdt.h" #endif @@ -166,14 +171,14 @@ WebServerThread *webServerThread; WebServerThread::WebServerThread() : concurrency::OSThread("WebServer") { - if (!config.network.wifi_enabled) { + if (!config.network.wifi_enabled && !config.network.eth_enabled) { disable(); } } int32_t WebServerThread::runOnce() { - if (!config.network.wifi_enabled) { + if (!config.network.wifi_enabled && !config.network.eth_enabled) { disable(); } diff --git a/src/mesh/udp/UdpMulticastThread.h b/src/mesh/udp/UdpMulticastThread.h index 9128d3b5c..69b1d2282 100644 --- a/src/mesh/udp/UdpMulticastThread.h +++ b/src/mesh/udp/UdpMulticastThread.h @@ -7,6 +7,11 @@ #include #include +#if HAS_ETHERNET && defined(USE_WS5500) +#include +#define ETH ETH2 +#endif // HAS_ETHERNET + #define UDP_MULTICAST_DEFAUL_PORT 4403 // Default port for UDP multicast is same as TCP api server #define UDP_MULTICAST_THREAD_INTERVAL_MS 15000 diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index ee50ee56f..92388d52a 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -9,6 +9,12 @@ #include "mesh/api/WiFiServerAPI.h" #include "target_specific.h" #include + +#if HAS_ETHERNET && defined(USE_WS5500) +#include +#define ETH ETH2 +#endif // HAS_ETHERNET + #include #ifdef ARCH_ESP32 #if !MESHTASTIC_EXCLUDE_WEBSERVER @@ -52,11 +58,28 @@ Syslog syslog(syslogClient); Periodic *wifiReconnect; +#ifdef USE_WS5500 +// Startup Ethernet +bool initEthernet() +{ + if ((config.network.eth_enabled) && (ETH.begin(ETH_PHY_W5500, 1, ETH_CS_PIN, ETH_INT_PIN, ETH_RST_PIN, SPI3_HOST, + ETH_SCLK_PIN, ETH_MISO_PIN, ETH_MOSI_PIN))) { + WiFi.onEvent(WiFiEvent); +#if !MESHTASTIC_EXCLUDE_WEBSERVER + createSSLCert(); // For WebServer +#endif + return true; + } + + return false; +} +#endif + static void onNetworkConnected() { if (!APStartupComplete) { // Start web server - LOG_INFO("Start WiFi network services"); + LOG_INFO("Start network services"); // start mdns if (!MDNS.begin("Meshtastic")) { @@ -188,6 +211,10 @@ bool isWifiAvailable() if (config.network.wifi_enabled && (config.network.wifi_ssid[0])) { return true; +#ifdef USE_WS5500 + } else if (config.network.eth_enabled) { + return true; +#endif } else { return false; } @@ -282,7 +309,7 @@ bool initWifi() // Called by the Espressif SDK to static void WiFiEvent(WiFiEvent_t event) { - LOG_DEBUG("WiFi-Event %d: ", event); + LOG_DEBUG("Network-Event %d: ", event); switch (event) { case ARDUINO_EVENT_WIFI_READY: @@ -377,19 +404,32 @@ static void WiFiEvent(WiFiEvent_t event) LOG_INFO("Ethernet started"); break; case ARDUINO_EVENT_ETH_STOP: + syslog.disable(); LOG_INFO("Ethernet stopped"); break; case ARDUINO_EVENT_ETH_CONNECTED: LOG_INFO("Ethernet connected"); break; case ARDUINO_EVENT_ETH_DISCONNECTED: + syslog.disable(); LOG_INFO("Ethernet disconnected"); break; case ARDUINO_EVENT_ETH_GOT_IP: - LOG_INFO("Obtained IP address (ARDUINO_EVENT_ETH_GOT_IP)"); +#ifdef USE_WS5500 + LOG_INFO("Obtained IP address: %s, %u Mbps, %s", ETH.localIP().toString().c_str(), ETH.linkSpeed(), + ETH.fullDuplex() ? "FULL_DUPLEX" : "HALF_DUPLEX"); + onNetworkConnected(); +#endif break; case ARDUINO_EVENT_ETH_GOT_IP6: - LOG_INFO("Obtained IP6 address (ARDUINO_EVENT_ETH_GOT_IP6)"); +#ifdef USE_WS5500 +#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0) + LOG_INFO("Obtained Local IP6 address: %s", ETH.linkLocalIPv6().toString().c_str()); + LOG_INFO("Obtained GlobalIP6 address: %s", ETH.globalIPv6().toString().c_str()); +#else + LOG_INFO("Obtained IP6 address: %s", ETH.localIPv6().toString().c_str()); +#endif +#endif break; case ARDUINO_EVENT_SC_SCAN_DONE: LOG_INFO("SmartConfig: Scan done"); diff --git a/src/mesh/wifi/WiFiAPClient.h b/src/mesh/wifi/WiFiAPClient.h index 5f4e2f5c9..078c40193 100644 --- a/src/mesh/wifi/WiFiAPClient.h +++ b/src/mesh/wifi/WiFiAPClient.h @@ -9,6 +9,11 @@ #include #endif +#if HAS_ETHERNET && defined(USE_WS5500) +#include +#define ETH ETH2 +#endif // HAS_ETHERNET + extern bool needReconnect; extern concurrency::Periodic *wifiReconnect; @@ -19,4 +24,9 @@ void deinitWifi(); bool isWifiAvailable(); -uint8_t getWifiDisconnectReason(); \ No newline at end of file +uint8_t getWifiDisconnectReason(); + +#ifdef USE_WS5500 +// Startup Ethernet +bool initEthernet(); +#endif \ No newline at end of file diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index ac0a8c0de..a765fb0b1 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -988,7 +988,7 @@ void AdminModule::handleGetDeviceConnectionStatus(const meshtastic_MeshPacket &r } #endif -#if HAS_ETHERNET +#if HAS_ETHERNET && !defined(USE_WS5500) conn.has_ethernet = true; conn.ethernet.has_status = true; if (Ethernet.linkStatus() == LinkON) { diff --git a/src/mqtt/MQTT.cpp b/src/mqtt/MQTT.cpp index 5f16f909f..226bee44d 100644 --- a/src/mqtt/MQTT.cpp +++ b/src/mqtt/MQTT.cpp @@ -19,6 +19,10 @@ #include "mesh/wifi/WiFiAPClient.h" #include #endif +#if HAS_ETHERNET && defined(USE_WS5500) +#include +#define ETH ETH2 +#endif // HAS_ETHERNET #include "Default.h" #if !defined(ARCH_NRF52) || NRF52_USE_JSON #include "serialization/JSON.h" @@ -295,6 +299,11 @@ bool connectPubSub(const PubSubConfig &config, PubSubClient &pubSub, Client &cli inline bool isConnectedToNetwork() { +#ifdef USE_WS5500 + if (ETH.connected()) + return true; +#endif + #if HAS_WIFI return WiFi.isConnected(); #elif HAS_ETHERNET diff --git a/src/mqtt/MQTT.h b/src/mqtt/MQTT.h index 5cda90218..0c260dc9c 100644 --- a/src/mqtt/MQTT.h +++ b/src/mqtt/MQTT.h @@ -14,7 +14,7 @@ #include #endif #endif -#if HAS_ETHERNET +#if HAS_ETHERNET && !defined(USE_WS5500) #include #endif diff --git a/src/platform/esp32/architecture.h b/src/platform/esp32/architecture.h index 742b295b5..e4f8b49a0 100644 --- a/src/platform/esp32/architecture.h +++ b/src/platform/esp32/architecture.h @@ -176,6 +176,8 @@ #define HW_VENDOR meshtastic_HardwareModel_SEEED_XIAO_S3 #elif defined(MESH_TAB) #define HW_VENDOR meshtastic_HardwareModel_MESH_TAB +#elif defined(T_ETH_ELITE) +#define HW_VENDOR meshtastic_HardwareModel_T_ETH_ELITE #endif // ----------------------------------------------------------------------------- diff --git a/src/platform/esp32/main-esp32.cpp b/src/platform/esp32/main-esp32.cpp index 679222af5..3b3557e95 100644 --- a/src/platform/esp32/main-esp32.cpp +++ b/src/platform/esp32/main-esp32.cpp @@ -26,7 +26,9 @@ #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !MESHTASTIC_EXCLUDE_BLUETOOTH void setBluetoothEnable(bool enable) { -#if HAS_WIFI +#ifdef USE_WS5500 + if ((config.bluetooth.enabled == true) && (config.network.wifi_enabled == false)) +#elif HAS_WIFI if (!isWifiAvailable() && config.bluetooth.enabled == true) #else if (config.bluetooth.enabled == true) diff --git a/variants/t-eth-elite/pins_arduino.h b/variants/t-eth-elite/pins_arduino.h new file mode 100644 index 000000000..cddd8d0b9 --- /dev/null +++ b/variants/t-eth-elite/pins_arduino.h @@ -0,0 +1,26 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#define USB_VID 0x303a +#define USB_PID 0x1001 + +// The default Wire will be mapped to PMU and RTC +static const uint8_t SDA = 17; +static const uint8_t SCL = 18; + +// Default SPI will be mapped to Radio +static const uint8_t SS = 40; +static const uint8_t MOSI = 11; +static const uint8_t MISO = 9; +static const uint8_t SCK = 10; + +#define SPI_MOSI (11) +#define SPI_SCK (10) +#define SPI_MISO (9) +#define SPI_CS (12) + +#define SDCARD_CS SPI_CS + +#endif /* Pins_Arduino_h */ \ No newline at end of file diff --git a/variants/t-eth-elite/platformio.ini b/variants/t-eth-elite/platformio.ini new file mode 100644 index 000000000..8c2f3bc37 --- /dev/null +++ b/variants/t-eth-elite/platformio.ini @@ -0,0 +1,16 @@ +[env:t-eth-elite] +extends = esp32s3_base +board = esp32s3box +board_check = true +build_flags = + ${esp32s3_base.build_flags} + -D T_ETH_ELITE + -I variants/t-eth-elite + -DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely. + +lib_ignore = + Ethernet + +lib_deps = + ${esp32s3_base.lib_deps} + https://github.com/meshtastic/ETHClass2#v1.0.0 diff --git a/variants/t-eth-elite/rfswitch.h b/variants/t-eth-elite/rfswitch.h new file mode 100644 index 000000000..589f24767 --- /dev/null +++ b/variants/t-eth-elite/rfswitch.h @@ -0,0 +1,11 @@ +#include "RadioLib.h" + +static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC}; + +static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + {LR11x0::MODE_STBY, {LOW, LOW}}, {LR11x0::MODE_RX, {HIGH, LOW}}, + {LR11x0::MODE_TX, {LOW, HIGH}}, {LR11x0::MODE_TX_HP, {LOW, HIGH}}, + {LR11x0::MODE_TX_HF, {LOW, LOW}}, {LR11x0::MODE_GNSS, {LOW, LOW}}, + {LR11x0::MODE_WIFI, {LOW, LOW}}, END_OF_MODE_TABLE, +}; diff --git a/variants/t-eth-elite/variant.h b/variants/t-eth-elite/variant.h new file mode 100644 index 000000000..b7ac05872 --- /dev/null +++ b/variants/t-eth-elite/variant.h @@ -0,0 +1,83 @@ +#define HAS_SDCARD +#define SDCARD_USE_SPI1 + +#define HAS_GPS 1 +#define GPS_RX_PIN 39 +#define GPS_TX_PIN 42 +#define GPS_BAUDRATE_FIXED 1 +#define GPS_BAUDRATE 9600 + +#define I2C_SDA 17 // I2C pins for this board +#define I2C_SCL 18 + +#define HAS_SCREEN 1 // Allow for OLED Screens on I2C Header of shield + +#define LED_PIN 38 // If defined we will blink this LED +#define BUTTON_PIN 0 // If defined, this will be used for user button presses, + +#define BUTTON_NEED_PULLUP + +// TTGO uses a common pinout for their SX1262 vs RF95 modules - both can be enabled and we will probe at runtime for RF95 and if +// not found then probe for SX1262 +#define USE_RF95 // RFM95/SX127x +#define USE_SX1262 +#define USE_SX1280 +#define USE_LR1121 + +#define LORA_SCK 10 +#define LORA_MISO 9 +#define LORA_MOSI 11 +#define LORA_CS 40 +#define LORA_RESET 46 + +// per SX1276_Receive_Interrupt/utilities.h +#define LORA_DIO0 8 +#define LORA_DIO1 16 +#define LORA_DIO2 RADIOLIB_NC + +// per SX1262_Receive_Interrupt/utilities.h +#ifdef USE_SX1262 +#define SX126X_CS LORA_CS +#define SX126X_DIO1 8 +#define SX126X_BUSY 16 +#define SX126X_RESET LORA_RESET +#define SX126X_DIO2_AS_RF_SWITCH +#define SX126X_DIO3_TCXO_VOLTAGE 1.8 +#endif + +// per SX128x_Receive_Interrupt/utilities.h +#ifdef USE_SX1280 +#define SX128X_CS LORA_CS +#define SX128X_DIO1 8 +#define SX128X_DIO2 33 +#define SX128X_DIO3 34 +#define SX128X_BUSY 16 +#define SX128X_RESET LORA_RESET +#define SX128X_RXEN 13 +#define SX128X_TXEN 38 +#define SX128X_MAX_POWER 3 +#endif + +// LR1121 +#ifdef USE_LR1121 +#define LR1121_IRQ_PIN 8 +#define LR1121_NRESET_PIN LORA_RESET +#define LR1121_BUSY_PIN 16 +#define LR1121_SPI_NSS_PIN LORA_CS +#define LR1121_SPI_SCK_PIN LORA_SCK +#define LR1121_SPI_MOSI_PIN LORA_MOSI +#define LR1121_SPI_MISO_PIN LORA_MISO +#define LR11X0_DIO3_TCXO_VOLTAGE 3.0 +#define LR11X0_DIO_AS_RF_SWITCH +#endif + +#define HAS_ETHERNET 1 +#define USE_WS5500 1 // this driver uses the same stack as the ESP32 Wifi driver + +#define ETH_MISO_PIN 47 +#define ETH_MOSI_PIN 21 +#define ETH_SCLK_PIN 48 +#define ETH_CS_PIN 45 +#define ETH_INT_PIN 14 +#define ETH_RST_PIN -1 +#define ETH_ADDR 1 \ No newline at end of file