diff --git a/src/helpers/esp32/TEthEliteBoard.cpp b/src/helpers/esp32/TEthEliteBoard.cpp new file mode 100644 index 00000000..42c669a5 --- /dev/null +++ b/src/helpers/esp32/TEthEliteBoard.cpp @@ -0,0 +1,162 @@ +#if defined(T_ETH_ELITE_SX1262) || defined(T_ETH_ELITE_SX1276) + +#include +#include +#include "driver/spi_common.h" +#include "driver/gpio.h" +#include +#include "TEthEliteBoard.h" +#include "target.h" +#include "helpers/ui/MomentaryButton.h" + +extern MomentaryButton user_btn; + +uint32_t deviceOnline = 0x00; +static SPIClass spi_eth(FSPI); +static ETHClass2 ETH; + +void TEthEliteBoard::begin() { + ESP32Board::begin(); + user_btn.begin(); + Wire1.begin(PIN_BOARD_SDA1, PIN_BOARD_SCL1); + #if ENV_INCLUDE_GPS + Serial1.begin(9600, SERIAL_8N1, PIN_GPS_RX, PIN_GPS_TX); + #endif + +#ifdef USE_ETHERNET + WiFi.mode(WIFI_OFF); +#endif + startNetwork(); + + pinMode(P_LORA_TX_LED, OUTPUT); + digitalWrite(P_LORA_TX_LED, LOW); + + esp_reset_reason_t reason = esp_reset_reason(); + if (reason == ESP_RST_DEEPSLEEP) { +#if defined(T_ETH_ELITE_SX1262) + long wakeup_source = esp_sleep_get_ext1_wakeup_status(); + if (wakeup_source & (1 << P_LORA_DIO_1)) { + startup_reason = BD_STARTUP_RX_PACKET; + } + rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS); + rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_1); +#elif defined(T_ETH_ELITE_SX1276) + long wakeup_source = esp_sleep_get_ext1_wakeup_status(); + if (wakeup_source & (1 << P_LORA_DIO_0)) { + startup_reason = BD_STARTUP_RX_PACKET; + } + rtc_gpio_hold_dis((gpio_num_t)P_LORA_NSS); + rtc_gpio_deinit((gpio_num_t)P_LORA_DIO_0); +#endif + } +} + +#ifdef MESH_DEBUG +void TEthEliteBoard::scanDevices(TwoWire *w) +{ + uint8_t err, addr; + int nDevices = 0; + + Serial.println("Scanning I2C for Devices"); + for (addr = 1; addr < 127; addr++) { + w->beginTransmission(addr); delay(2); + err = w->endTransmission(); + if (err == 0) { + nDevices++; + switch (addr) { + case 0x77: + case 0x76: + Serial.println("\tFound BME280 Sensor"); + deviceOnline |= BME280_ONLINE; + break; + case 0x34: + Serial.println("\tFound AXP192/AXP2101 PMU"); + deviceOnline |= POWERMANAGE_ONLINE; + break; + case 0x3C: + Serial.println("\tFound SSD1306/SH1106 display"); + deviceOnline |= DISPLAY_ONLINE; + break; + case 0x51: + Serial.println("\tFound PCF8563 RTC"); + deviceOnline |= PCF8563_ONLINE; + break; + case 0x1C: + Serial.println("\tFound QMC6310 MAG Sensor"); + deviceOnline |= QMC6310_ONLINE; + break; + default: + Serial.printf("\tI2C device found at address 0x%02X\n", addr); + break; + } + } else if (err == 4) { + Serial.printf("Unknown error at address 0x%02X\n", addr); + } + } + if (nDevices == 0) + Serial.println("No I2C devices found"); + + Serial.println("Scan complete."); + Serial.printf("GPS RX pin: %d, GPS TX pin: %d\n", PIN_GPS_RX, PIN_GPS_TX); +} + +void TEthEliteBoard::printPMU() +{ + Serial.print("isCharging:"); Serial.println(PMU->isCharging() ? "YES" : "NO"); + Serial.print("isDischarge:"); Serial.println(PMU->isDischarge() ? "YES" : "NO"); + Serial.print("isVbusIn:"); Serial.println(PMU->isVbusIn() ? "YES" : "NO"); + Serial.print("getBattVoltage:"); Serial.print(PMU->getBattVoltage()); Serial.println("mV"); + Serial.print("getVbusVoltage:"); Serial.print(PMU->getVbusVoltage()); Serial.println("mV"); + Serial.print("getSystemVoltage:"); Serial.print(PMU->getSystemVoltage()); Serial.println("mV"); + if (PMU->isBatteryConnect()) { + Serial.print("getBatteryPercent:"); Serial.print(PMU->getBatteryPercent()); Serial.println("%"); + } +} +#endif + +void TEthEliteBoard::startNetwork() { +#ifdef USE_ETHERNET + startEthernet(); +#elif defined(WIFI_SSID) + startWifi(); +#endif +} + +void TEthEliteBoard::startEthernet() { + pinMode(ETH_CS, OUTPUT); + digitalWrite(ETH_CS, HIGH); + + ETH.begin(ETH_PHY_W5500, ETH_ADDR, ETH_CS, ETH_INT, -1, SPI2_HOST, ETH_SCLK, ETH_MISO, ETH_MOSI); + delay(100); + +#ifdef ETH_STATIC_IP + IPAddress ip(ETH_STATIC_IP); + IPAddress gw(ETH_GATEWAY); + IPAddress mask(ETH_SUBNET); + IPAddress dns(ETH_DNS); + ETH.config(ip, gw, mask, dns); +#endif + + unsigned long t0 = millis(); + while (!ETH.linkUp() && millis() - t0 < 5000) { + delay(100); + } + + t0 = millis(); + while (ETH.localIP() == IPAddress(0, 0, 0, 0) && millis() - t0 < 5000) { + delay(100); + } + + if (ETH.localIP() == IPAddress(0, 0, 0, 0)) { + Serial.println("DHCP timeout, using fallback IP"); + ETH.config(IPAddress(192, 168, 4, 2), IPAddress(192, 168, 4, 1), IPAddress(255, 255, 255, 0)); + } + + uint8_t mac[6]; + ETH.macAddress(mac); + Serial.printf("ETH MAC %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + Serial.print("ETH IP "); Serial.println(ETH.localIP()); + Serial.println(ETH.linkUp() ? "ETH LINK UP" : "ETH LINK DOWN"); +} + +#endif diff --git a/src/helpers/esp32/TEthEliteBoard.h b/src/helpers/esp32/TEthEliteBoard.h new file mode 100644 index 00000000..d009be3f --- /dev/null +++ b/src/helpers/esp32/TEthEliteBoard.h @@ -0,0 +1,7 @@ +#pragma once + +#if defined(T_ETH_ELITE_SX1262) + #include "TEthEliteBoard_SX1262.h" +#elif defined(T_ETH_ELITE_SX1276) + #include "TEthEliteBoard_SX1276.h" +#endif diff --git a/src/helpers/esp32/TEthEliteBoard_SX1262.h b/src/helpers/esp32/TEthEliteBoard_SX1262.h new file mode 100644 index 00000000..2105aa2d --- /dev/null +++ b/src/helpers/esp32/TEthEliteBoard_SX1262.h @@ -0,0 +1,102 @@ +#pragma once + +#if defined(T_ETH_ELITE_SX1262) + +// Define pin mappings BEFORE including ESP32Board.h so sleep() can use P_LORA_DIO_1 + +// LoRa SX1262 pins (T-ETH Elite LoRa Shield) +#define P_LORA_NSS 40 // CS +#define P_LORA_RESET 46 // RESET +#define P_LORA_BUSY 16 // BUSY +#define P_LORA_DIO_0 -1 // NC +#define P_LORA_DIO_1 8 // IRQ +#define P_LORA_TX_LED 38 +#define P_LORA_SCLK 10 +#define P_LORA_MISO 9 +#define P_LORA_MOSI 11 + +// ETH W5500 pins (T-ETH Elite main board) +#define ETH_MISO 47 +#define ETH_MOSI 21 +#define ETH_SCLK 48 +#define ETH_CS 45 +#define ETH_INT 14 +#define ETH_RST -1 +#define ETH_ADDR 1 + +// I2C bus (Wire1) +#define PIN_BOARD_SDA1 17 +#define PIN_BOARD_SCL1 18 + +// GPS pins (LoRa Shield) +#define PIN_GPS_RX 39 +#define PIN_GPS_TX 42 +#define PIN_GPS_EN -1 + +// Analog button +#define PIN_USER_BTN_ANA 7 + +// Include headers AFTER pin definitions so ESP32Board::sleep() can use P_LORA_DIO_1 +#include +#include +#include "XPowersLib.h" +#include "helpers/ESP32Board.h" +#include + +class TEthEliteBoard : public ESP32Board { + XPowersLibInterface *PMU = NULL; + + enum { + POWERMANAGE_ONLINE = _BV(0), + DISPLAY_ONLINE = _BV(1), + RADIO_ONLINE = _BV(2), + GPS_ONLINE = _BV(3), + PSRAM_ONLINE = _BV(4), + SDCARD_ONLINE = _BV(5), + AXDL345_ONLINE = _BV(6), + BME280_ONLINE = _BV(7), + BMP280_ONLINE = _BV(8), + BME680_ONLINE = _BV(9), + QMC6310_ONLINE = _BV(10), + QMI8658_ONLINE = _BV(11), + PCF8563_ONLINE = _BV(12), + OSC32768_ONLINE = _BV(13), + }; + +public: + +#ifdef MESH_DEBUG + void printPMU(); + void scanDevices(TwoWire *w); +#endif + void begin(); + void startNetwork(); + void startEthernet(); + void startWifi(); + + void enterDeepSleep(uint32_t secs, int pin_wake_btn) { + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + + rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY); + rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1); + rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS); + + if (pin_wake_btn < 0) { + esp_sleep_enable_ext1_wakeup((1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); + } else { + esp_sleep_enable_ext1_wakeup((1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); + } + + if (secs > 0) { + esp_sleep_enable_timer_wakeup(secs * 1000000); + } + + esp_deep_sleep_start(); + } + + uint16_t getBattMilliVolts() { return 0; } + + const char* getManufacturerName() const { return "LilyGo T-ETH-Elite"; } +}; + +#endif diff --git a/src/helpers/esp32/TEthEliteBoard_SX1276.h b/src/helpers/esp32/TEthEliteBoard_SX1276.h new file mode 100644 index 00000000..a18d7625 --- /dev/null +++ b/src/helpers/esp32/TEthEliteBoard_SX1276.h @@ -0,0 +1,102 @@ +#pragma once + +#if defined(T_ETH_ELITE_SX1276) + +// Define pin mappings BEFORE including ESP32Board.h so sleep() can use P_LORA_DIO_0 + +// LoRa SX1276 pins (T-ETH Elite LoRa Shield) +#define P_LORA_DIO_0 8 // IRQ (DIO0 on SX1276) +#define P_LORA_DIO_1 16 // DIO1 +#define P_LORA_NSS 40 // CS +#define P_LORA_RESET 46 // RESET +#define P_LORA_BUSY -1 // SX1276 has no BUSY pin +#define P_LORA_TX_LED 38 +#define P_LORA_SCLK 10 +#define P_LORA_MISO 9 +#define P_LORA_MOSI 11 + +// ETH W5500 pins (T-ETH Elite main board) +#define ETH_MISO 47 +#define ETH_MOSI 21 +#define ETH_SCLK 48 +#define ETH_CS 45 +#define ETH_INT 14 +#define ETH_RST -1 +#define ETH_ADDR 1 + +// I2C bus (Wire1) +#define PIN_BOARD_SDA1 17 +#define PIN_BOARD_SCL1 18 + +// GPS pins (LoRa Shield) +#define PIN_GPS_RX 39 +#define PIN_GPS_TX 42 +#define PIN_GPS_EN -1 + +// Analog button +#define PIN_USER_BTN_ANA 7 + +// Include headers AFTER pin definitions so ESP32Board::sleep() can use P_LORA_DIO_0 +#include +#include +#include "XPowersLib.h" +#include "helpers/ESP32Board.h" +#include + +class TEthEliteBoard : public ESP32Board { + XPowersLibInterface *PMU = NULL; + + enum { + POWERMANAGE_ONLINE = _BV(0), + DISPLAY_ONLINE = _BV(1), + RADIO_ONLINE = _BV(2), + GPS_ONLINE = _BV(3), + PSRAM_ONLINE = _BV(4), + SDCARD_ONLINE = _BV(5), + AXDL345_ONLINE = _BV(6), + BME280_ONLINE = _BV(7), + BMP280_ONLINE = _BV(8), + BME680_ONLINE = _BV(9), + QMC6310_ONLINE = _BV(10), + QMI8658_ONLINE = _BV(11), + PCF8563_ONLINE = _BV(12), + OSC32768_ONLINE = _BV(13), + }; + +public: + +#ifdef MESH_DEBUG + void printPMU(); + void scanDevices(TwoWire *w); +#endif + void begin(); + void startNetwork(); + void startEthernet(); + void startWifi(); + + void enterDeepSleep(uint32_t secs, int pin_wake_btn) { + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + + rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_0, RTC_GPIO_MODE_INPUT_ONLY); + rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_0); + rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS); + + if (pin_wake_btn < 0) { + esp_sleep_enable_ext1_wakeup((1L << P_LORA_DIO_0), ESP_EXT1_WAKEUP_ANY_HIGH); + } else { + esp_sleep_enable_ext1_wakeup((1L << P_LORA_DIO_0) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); + } + + if (secs > 0) { + esp_sleep_enable_timer_wakeup(secs * 1000000); + } + + esp_deep_sleep_start(); + } + + uint16_t getBattMilliVolts() { return 0; } + + const char* getManufacturerName() const { return "LilyGo T-ETH-Elite"; } +}; + +#endif diff --git a/variants/lilygo_t_eth_elite_sx1262/platformio.ini b/variants/lilygo_t_eth_elite_sx1262/platformio.ini new file mode 100644 index 00000000..f3f0c2cb --- /dev/null +++ b/variants/lilygo_t_eth_elite_sx1262/platformio.ini @@ -0,0 +1,177 @@ +[LilyGo_T_ETH_Elite_SX1262] +extends = esp32_base +board = t_eth_elite +upload_protocol = esptool +board_build.partitions = default_16MB.csv +board_upload.flash_size = 16MB +board_upload.maximum_size = 16777216 +build_flags = + ${esp32_base.build_flags} + -I variants/lilygo_t_eth_elite_sx1262 + -D T_ETH_ELITE_SX1262 + -D RADIO_CLASS=CustomSX1262 + -D WRAPPER_CLASS=CustomSX1262Wrapper + -D SX126X_CURRENT_LIMIT=140 + -D SX126X_RX_BOOSTED_GAIN=1 + -D LORA_TX_POWER=22 + -D ENV_INCLUDE_GPS=1 + -D PIN_GPS_RX=39 + -D PIN_GPS_TX=42 + -D PIN_GPS_EN=-1 +build_src_filter = ${esp32_base.build_src_filter} + +<../variants/lilygo_t_eth_elite_sx1262> + + + + +lib_deps = + ${esp32_base.lib_deps} + lewisxhe/XPowersLib @ ^0.2.7 + stevemarple/MicroNMEA @ ^2.0.6 + adafruit/Adafruit BME280 Library @ ^2.3.0 + +; === LilyGo T-ETH-Elite with SX1262 environments === + +[env:LilyGo_T_ETH_Elite_SX1262_repeater] +extends = LilyGo_T_ETH_Elite_SX1262 +build_flags = + ${LilyGo_T_ETH_Elite_SX1262.build_flags} + -D ADVERT_NAME='"T-ETH Elite SX1262 Repeater"' + -D ADVERT_LAT=0 + -D ADVERT_LON=0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1262.build_src_filter} + +<../examples/simple_repeater> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1262.lib_deps} + ${esp32_ota.lib_deps} + +[env:LilyGo_T_ETH_Elite_SX1262_repeater_eth] +extends = LilyGo_T_ETH_Elite_SX1262 +build_flags = + ${LilyGo_T_ETH_Elite_SX1262.build_flags} + -D ADVERT_NAME='"T-ETH Elite SX1262 Repeater"' + -D ADVERT_LAT=0 + -D ADVERT_LON=0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 + -D USE_ETHERNET + -D ETH_STATIC_IP=192,168,254,20 + -D ETH_GATEWAY=192,168,254,254 + -D ETH_SUBNET=255,255,255,0 + -D ETH_DNS=8,8,8,8 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1262.build_src_filter} + +<../examples/simple_repeater> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1262.lib_deps} + ${esp32_ota.lib_deps} + +[env:LilyGo_T_ETH_Elite_SX1262_repeater_bridge_espnow] +extends = LilyGo_T_ETH_Elite_SX1262 +build_flags = + ${LilyGo_T_ETH_Elite_SX1262.build_flags} + -D ADVERT_NAME='"T-ETH Elite SX1262 ESPNow Bridge"' + -D ADVERT_LAT=0 + -D ADVERT_LON=0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 + -D WITH_ESPNOW_BRIDGE=1 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1262.build_src_filter} + + + +<../examples/simple_repeater> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1262.lib_deps} + ${esp32_ota.lib_deps} + +[env:LilyGo_T_ETH_Elite_SX1262_room_server] +extends = LilyGo_T_ETH_Elite_SX1262 +build_flags = + ${LilyGo_T_ETH_Elite_SX1262.build_flags} + -D ADVERT_NAME='"T-ETH Elite SX1262 Room"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D ROOM_PASSWORD='"hello"' +build_src_filter = ${LilyGo_T_ETH_Elite_SX1262.build_src_filter} + +<../examples/simple_room_server> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1262.lib_deps} + ${esp32_ota.lib_deps} + +[env:LilyGo_T_ETH_Elite_SX1262_room_server_eth] +extends = LilyGo_T_ETH_Elite_SX1262 +build_flags = + ${LilyGo_T_ETH_Elite_SX1262.build_flags} + -D ADVERT_NAME='"T-ETH Elite SX1262 Room"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D ROOM_PASSWORD='"hello"' + -D USE_ETHERNET + -D ETH_STATIC_IP=192,168,254,20 + -D ETH_GATEWAY=192,168,254,254 + -D ETH_SUBNET=255,255,255,0 + -D ETH_DNS=8,8,8,8 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1262.build_src_filter} + +<../examples/simple_room_server> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1262.lib_deps} + ${esp32_ota.lib_deps} + +[env:LilyGo_T_ETH_Elite_SX1262_companion_radio_eth] +extends = LilyGo_T_ETH_Elite_SX1262 +build_flags = + ${LilyGo_T_ETH_Elite_SX1262.build_flags} + -I examples/companion_radio/ui-new + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D OFFLINE_QUEUE_SIZE=256 + -D USE_ETHERNET + -D ETH_STATIC_IP=192,168,254,20 + -D ETH_GATEWAY=192,168,254,254 + -D ETH_SUBNET=255,255,255,0 + -D ETH_DNS=8,8,8,8 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1262.build_src_filter} + + + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1262.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:LilyGo_T_ETH_Elite_SX1262_companion_radio_wifi] +extends = LilyGo_T_ETH_Elite_SX1262 +build_flags = + ${LilyGo_T_ETH_Elite_SX1262.build_flags} + -I examples/companion_radio/ui-new + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D OFFLINE_QUEUE_SIZE=256 + -D WIFI_SSID='"WIFI_SSID"' + -D WIFI_PWD='"Password"' +build_src_filter = ${LilyGo_T_ETH_Elite_SX1262.build_src_filter} + + + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1262.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:LilyGo_T_ETH_Elite_SX1262_companion_radio_ble] +extends = LilyGo_T_ETH_Elite_SX1262 +build_flags = + ${LilyGo_T_ETH_Elite_SX1262.build_flags} + -I examples/companion_radio/ui-new + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D BLE_PIN_CODE=123456 + -D OFFLINE_QUEUE_SIZE=256 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1262.build_src_filter} + + + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1262.lib_deps} + densaugeo/base64 @ ~1.4.0 diff --git a/variants/lilygo_t_eth_elite_sx1262/target.cpp b/variants/lilygo_t_eth_elite_sx1262/target.cpp new file mode 100644 index 00000000..b6ce2c49 --- /dev/null +++ b/variants/lilygo_t_eth_elite_sx1262/target.cpp @@ -0,0 +1,53 @@ +#include +#include "helpers/ui/MomentaryButton.h" +#include "target.h" + +TEthEliteBoard board; + +#ifdef DISPLAY_CLASS + DISPLAY_CLASS display; +#endif + +MomentaryButton user_btn(PIN_USER_BTN_ANA, 1000, true); + +static SPIClass spi; +RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi); + +WRAPPER_CLASS radio_driver(radio, board); + +ESP32RTCClock fallback_clock; +AutoDiscoverRTCClock rtc_clock(fallback_clock); + +#if ENV_INCLUDE_GPS + #include + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); +#else + EnvironmentSensorManager sensors; +#endif + +bool radio_init() { + fallback_clock.begin(); + rtc_clock.begin(Wire1); + return radio.std_init(&spi); +} + +uint32_t radio_get_rng_seed() { + return radio.random(0x7FFFFFFF); +} + +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { + radio.setFrequency(freq); + radio.setSpreadingFactor(sf); + radio.setBandwidth(bw); + radio.setCodingRate(cr); +} + +void radio_set_tx_power(int8_t dbm) { + radio.setOutputPower(dbm); +} + +mesh::LocalIdentity radio_new_identity() { + RadioNoiseListener rng(radio); + return mesh::LocalIdentity(&rng); +} diff --git a/variants/lilygo_t_eth_elite_sx1262/target.h b/variants/lilygo_t_eth_elite_sx1262/target.h new file mode 100644 index 00000000..e3635b57 --- /dev/null +++ b/variants/lilygo_t_eth_elite_sx1262/target.h @@ -0,0 +1,30 @@ +#pragma once + +#define HAS_ETHERNET 1 + +#define RADIOLIB_STATIC_ONLY 1 +#include +#include +#include +#include +#include +#include +#include + +extern MomentaryButton user_btn; + +#ifdef DISPLAY_CLASS + #include + extern DISPLAY_CLASS display; +#endif + +extern TEthEliteBoard board; +extern WRAPPER_CLASS radio_driver; +extern AutoDiscoverRTCClock rtc_clock; +extern EnvironmentSensorManager sensors; + +bool radio_init(); +uint32_t radio_get_rng_seed(); +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); +void radio_set_tx_power(int8_t dbm); +mesh::LocalIdentity radio_new_identity(); diff --git a/variants/lilygo_t_eth_elite_sx1276/platformio.ini b/variants/lilygo_t_eth_elite_sx1276/platformio.ini new file mode 100644 index 00000000..512c650b --- /dev/null +++ b/variants/lilygo_t_eth_elite_sx1276/platformio.ini @@ -0,0 +1,176 @@ +[LilyGo_T_ETH_Elite_SX1276] +extends = esp32_base +board = t_eth_elite +upload_protocol = esptool +board_build.partitions = default_16MB.csv +board_upload.flash_size = 16MB +board_upload.maximum_size = 16777216 +build_flags = + ${esp32_base.build_flags} + -I variants/lilygo_t_eth_elite_sx1276 + -D T_ETH_ELITE_SX1276 + -D RADIO_CLASS=CustomSX1276 + -D WRAPPER_CLASS=CustomSX1276Wrapper + -D SX127X_CURRENT_LIMIT=120 + -D LORA_TX_POWER=20 + -D ENV_INCLUDE_GPS=1 + -D PIN_GPS_RX=39 + -D PIN_GPS_TX=42 + -D PIN_GPS_EN=-1 +build_src_filter = ${esp32_base.build_src_filter} + +<../variants/lilygo_t_eth_elite_sx1276> + + + + +lib_deps = + ${esp32_base.lib_deps} + lewisxhe/XPowersLib @ ^0.2.7 + stevemarple/MicroNMEA @ ^2.0.6 + adafruit/Adafruit BME280 Library @ ^2.3.0 + +; === LilyGo T-ETH-Elite with SX1276 environments === + +[env:LilyGo_T_ETH_Elite_SX1276_repeater] +extends = LilyGo_T_ETH_Elite_SX1276 +build_flags = + ${LilyGo_T_ETH_Elite_SX1276.build_flags} + -D ADVERT_NAME='"T-ETH Elite SX1276 Repeater"' + -D ADVERT_LAT=0 + -D ADVERT_LON=0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1276.build_src_filter} + +<../examples/simple_repeater> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1276.lib_deps} + ${esp32_ota.lib_deps} + +[env:LilyGo_T_ETH_Elite_SX1276_repeater_eth] +extends = LilyGo_T_ETH_Elite_SX1276 +build_flags = + ${LilyGo_T_ETH_Elite_SX1276.build_flags} + -D ADVERT_NAME='"T-ETH Elite SX1276 Repeater"' + -D ADVERT_LAT=0 + -D ADVERT_LON=0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 + -D USE_ETHERNET + -D ETH_STATIC_IP=192,168,254,20 + -D ETH_GATEWAY=192,168,254,254 + -D ETH_SUBNET=255,255,255,0 + -D ETH_DNS=8,8,8,8 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1276.build_src_filter} + +<../examples/simple_repeater> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1276.lib_deps} + ${esp32_ota.lib_deps} + +[env:LilyGo_T_ETH_Elite_SX1276_repeater_bridge_espnow] +extends = LilyGo_T_ETH_Elite_SX1276 +build_flags = + ${LilyGo_T_ETH_Elite_SX1276.build_flags} + -D ADVERT_NAME='"T-ETH Elite SX1276 ESPNow Bridge"' + -D ADVERT_LAT=0 + -D ADVERT_LON=0 + -D ADMIN_PASSWORD='"password"' + -D MAX_NEIGHBOURS=50 + -D WITH_ESPNOW_BRIDGE=1 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1276.build_src_filter} + + + +<../examples/simple_repeater> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1276.lib_deps} + ${esp32_ota.lib_deps} + +[env:LilyGo_T_ETH_Elite_SX1276_room_server] +extends = LilyGo_T_ETH_Elite_SX1276 +build_flags = + ${LilyGo_T_ETH_Elite_SX1276.build_flags} + -D ADVERT_NAME='"T-ETH Elite SX1276 Room"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D ROOM_PASSWORD='"hello"' +build_src_filter = ${LilyGo_T_ETH_Elite_SX1276.build_src_filter} + +<../examples/simple_room_server> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1276.lib_deps} + ${esp32_ota.lib_deps} + +[env:LilyGo_T_ETH_Elite_SX1276_room_server_eth] +extends = LilyGo_T_ETH_Elite_SX1276 +build_flags = + ${LilyGo_T_ETH_Elite_SX1276.build_flags} + -D ADVERT_NAME='"T-ETH Elite SX1276 Room"' + -D ADVERT_LAT=0.0 + -D ADVERT_LON=0.0 + -D ADMIN_PASSWORD='"password"' + -D ROOM_PASSWORD='"hello"' + -D USE_ETHERNET + -D ETH_STATIC_IP=192,168,254,20 + -D ETH_GATEWAY=192,168,254,254 + -D ETH_SUBNET=255,255,255,0 + -D ETH_DNS=8,8,8,8 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1276.build_src_filter} + +<../examples/simple_room_server> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1276.lib_deps} + ${esp32_ota.lib_deps} + +[env:LilyGo_T_ETH_Elite_SX1276_companion_radio_eth] +extends = LilyGo_T_ETH_Elite_SX1276 +build_flags = + ${LilyGo_T_ETH_Elite_SX1276.build_flags} + -I examples/companion_radio/ui-new + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D OFFLINE_QUEUE_SIZE=256 + -D USE_ETHERNET + -D ETH_STATIC_IP=192,168,254,20 + -D ETH_GATEWAY=192,168,254,254 + -D ETH_SUBNET=255,255,255,0 + -D ETH_DNS=8,8,8,8 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1276.build_src_filter} + + + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1276.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:LilyGo_T_ETH_Elite_SX1276_companion_radio_wifi] +extends = LilyGo_T_ETH_Elite_SX1276 +build_flags = + ${LilyGo_T_ETH_Elite_SX1276.build_flags} + -I examples/companion_radio/ui-new + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D OFFLINE_QUEUE_SIZE=256 + -D WIFI_SSID='"WIFI_SSID"' + -D WIFI_PWD='"Password"' +build_src_filter = ${LilyGo_T_ETH_Elite_SX1276.build_src_filter} + + + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1276.lib_deps} + densaugeo/base64 @ ~1.4.0 + +[env:LilyGo_T_ETH_Elite_SX1276_companion_radio_ble] +extends = LilyGo_T_ETH_Elite_SX1276 +build_flags = + ${LilyGo_T_ETH_Elite_SX1276.build_flags} + -I examples/companion_radio/ui-new + -D MAX_CONTACTS=350 + -D MAX_GROUP_CHANNELS=40 + -D BLE_PIN_CODE=123456 + -D OFFLINE_QUEUE_SIZE=256 +build_src_filter = ${LilyGo_T_ETH_Elite_SX1276.build_src_filter} + + + + + +<../examples/companion_radio/*.cpp> + +<../examples/companion_radio/ui-new/*.cpp> +lib_deps = + ${LilyGo_T_ETH_Elite_SX1276.lib_deps} + densaugeo/base64 @ ~1.4.0 diff --git a/variants/lilygo_t_eth_elite_sx1276/target.cpp b/variants/lilygo_t_eth_elite_sx1276/target.cpp new file mode 100644 index 00000000..a311c1d7 --- /dev/null +++ b/variants/lilygo_t_eth_elite_sx1276/target.cpp @@ -0,0 +1,56 @@ +#include +#include "helpers/ui/MomentaryButton.h" +#include "target.h" + +TEthEliteBoard board; + +#ifdef DISPLAY_CLASS + DISPLAY_CLASS display; +#endif + +MomentaryButton user_btn(PIN_USER_BTN_ANA, 1000, true); + +static SPIClass spi; +RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi); + +WRAPPER_CLASS radio_driver(radio, board); + +ESP32RTCClock fallback_clock; +AutoDiscoverRTCClock rtc_clock(fallback_clock); + +#if ENV_INCLUDE_GPS + #include + MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1); + EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); +#else + EnvironmentSensorManager sensors; +#endif + +bool radio_init() { + fallback_clock.begin(); + rtc_clock.begin(Wire1); + spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI); + bool ok = radio.std_init(&spi); + delay(100); // allow SX1276 to stabilize after init + return ok; +} + +uint32_t radio_get_rng_seed() { + return radio.random(0x7FFFFFFF); +} + +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr) { + radio.setFrequency(freq); + radio.setSpreadingFactor(sf); + radio.setBandwidth(bw); + radio.setCodingRate(cr); +} + +void radio_set_tx_power(int8_t dbm) { + radio.setOutputPower(dbm); +} + +mesh::LocalIdentity radio_new_identity() { + RadioNoiseListener rng(radio); + return mesh::LocalIdentity(&rng); +} diff --git a/variants/lilygo_t_eth_elite_sx1276/target.h b/variants/lilygo_t_eth_elite_sx1276/target.h new file mode 100644 index 00000000..4861b535 --- /dev/null +++ b/variants/lilygo_t_eth_elite_sx1276/target.h @@ -0,0 +1,30 @@ +#pragma once + +#define HAS_ETHERNET 1 + +#define RADIOLIB_STATIC_ONLY 1 +#include +#include +#include +#include +#include +#include +#include + +extern MomentaryButton user_btn; + +#ifdef DISPLAY_CLASS + #include + extern DISPLAY_CLASS display; +#endif + +extern TEthEliteBoard board; +extern WRAPPER_CLASS radio_driver; +extern AutoDiscoverRTCClock rtc_clock; +extern EnvironmentSensorManager sensors; + +bool radio_init(); +uint32_t radio_get_rng_seed(); +void radio_set_params(float freq, float bw, uint8_t sf, uint8_t cr); +void radio_set_tx_power(int8_t dbm); +mesh::LocalIdentity radio_new_identity();