From 0c888e859c61a168bc0e5fed615cd24a9a7aa1e8 Mon Sep 17 00:00:00 2001 From: frogmane Date: Sun, 9 Mar 2025 00:15:19 -0500 Subject: [PATCH 1/7] esp8285 attempt --- boards/esp8285-8285.json | 35 +++++++ examples/companion_radio/main.cpp | 74 +++++++++++--- examples/simple_repeater/main.cpp | 6 +- examples/simple_secure_chat/main.cpp | 2 +- platformio.ini | 41 ++++++++ src/helpers/CommonCLI.cpp | 12 ++- src/helpers/ESP8285Board.h | 103 ++++++++++++++++++++ src/helpers/IdentityStore.cpp | 12 +++ src/helpers/IdentityStore.h | 2 +- src/helpers/RadioLibWrappers.cpp | 2 +- src/helpers/esp8285/SerialWifiInterface.cpp | 93 ++++++++++++++++++ src/helpers/esp8285/SerialWifiInterface.h | 59 +++++++++++ 12 files changed, 422 insertions(+), 19 deletions(-) create mode 100644 boards/esp8285-8285.json create mode 100644 src/helpers/ESP8285Board.h create mode 100644 src/helpers/esp8285/SerialWifiInterface.cpp create mode 100644 src/helpers/esp8285/SerialWifiInterface.h diff --git a/boards/esp8285-8285.json b/boards/esp8285-8285.json new file mode 100644 index 00000000..640c0a26 --- /dev/null +++ b/boards/esp8285-8285.json @@ -0,0 +1,35 @@ +{ + "comment": "esp8285 variant for ExpressLRS that uses variant=esp8285 instead of variant=generic", + "build": { + "arduino": { + "ldscript": "eagle.flash.1m256.ld", + "memory_type": "qio_qspi" + }, + "core": "esp8266", + "extra_flags": "-DESP8266 -DESP8285 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01", + "f_cpu": "80000000L", + "f_flash": "40000000L", + "flash_mode": "dout", + "mcu": "esp8266", + "variant": "esp8285" + }, + "connectivity": [ + "wifi" + ], + "frameworks": [ + "arduino", + "espidf", + "esp8266-rtos-sdk", + "esp8266-nonos-sdk" + ], + "name": "Generic ESP8285 Module", + "upload": { + "maximum_ram_size": 81920, + "maximum_size": 1048576, + "require_upload_port": true, + "resetmethod": "ck", + "speed": 115200 + }, + "url": "http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family", + "vendor": "Espressif" + } \ No newline at end of file diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 5cfeac60..50ffe041 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -3,8 +3,10 @@ #if defined(NRF52_PLATFORM) #include -#elif defined(ESP32) +#elif defined(ESP32) #include +#elif defined(ESP8285) || defined(ESP866) + #include #endif #define RADIOLIB_STATIC_ONLY 1 @@ -92,6 +94,10 @@ #include #include static TechoBoard board; +#elif defined(ESP8285) + #include + #include + static ESP8285Board board; #else #error "need to provide a 'board' object" #endif @@ -243,7 +249,12 @@ class MyMesh : public BaseChatMesh { void loadContacts() { if (_fs->exists("/contacts3")) { - File file = _fs->open("/contacts3"); + + #if defined(ESP8285) + File file = _fs->open("/contacts3", "r"); + #else + File file = _fs->open("/contacts3"); + #endif if (file) { bool full = false; while (!full) { @@ -279,7 +290,11 @@ class MyMesh : public BaseChatMesh { File file = _fs->open("/contacts3", FILE_O_WRITE); if (file) { file.seek(0); file.truncate(); } #else + #if defined(ESP8285) + File file = _fs->open("/contacts3", "w"); + #else File file = _fs->open("/contacts3", "w", true); + #endif #endif if (file) { ContactsIterator iter; @@ -315,7 +330,11 @@ class MyMesh : public BaseChatMesh { sprintf(path, "/bl/%s", fname); if (_fs->exists(path)) { - File f = _fs->open(path); + #if defined(ESP8285) + File f = _fs->open(path, "r"); + #else + File f = _fs->open(path); + #endif if (f) { int len = f.read(dest_buf, 255); // currently MAX 255 byte blob len supported!! f.close(); @@ -336,8 +355,12 @@ class MyMesh : public BaseChatMesh { #if defined(NRF52_PLATFORM) File f = _fs->open(path, FILE_O_WRITE); if (f) { f.seek(0); f.truncate(); } + #else + #if defined(ESP8285) + File f = _fs->open(path, "w"); #else File f = _fs->open(path, "w", true); + #endif #endif if (f) { int n = f.write(src_buf, len); @@ -644,7 +667,11 @@ class MyMesh : public BaseChatMesh { // load persisted prefs if (_fs->exists("/node_prefs")) { - File file = _fs->open("/node_prefs"); + #if defined(ESP8285) + File file = _fs->open("/node_prefs", "r"); + #else + File file = _fs->open("/node_prefs"); + #endif if (file) { uint8_t pad[8]; @@ -718,7 +745,11 @@ class MyMesh : public BaseChatMesh { File file = _fs->open("/node_prefs", FILE_O_WRITE); if (file) { file.seek(0); file.truncate(); } #else + #if defined(ESP8285) + File file = _fs->open("/node_prefs", "w"); + #else File file = _fs->open("/node_prefs", "w", true); + #endif #endif if (file) { uint8_t pad[8]; @@ -1198,6 +1229,17 @@ class MyMesh : public BaseChatMesh { #include ArduinoSerialInterface serial_interface; #endif +#elif defined(ESP8285) + #ifdef WIFI_SSID + #include + SerialWifiInterface serial_interface; + #ifndef TCP_PORT + #define TCP_PORT 5000 + #endif + #else + #include + ArduinoSerialInterface serial_interface; + #endif #elif defined(NRF52_PLATFORM) #ifdef BLE_PIN_CODE #include @@ -1270,19 +1312,25 @@ void setup() { InternalFS.begin(); the_mesh.begin(InternalFS, trng); -#ifdef BLE_PIN_CODE - char dev_name[32+10]; - sprintf(dev_name, "MeshCore-%s", the_mesh.getNodeName()); - serial_interface.begin(dev_name, the_mesh.getBLEPin()); -#else - pinMode(WB_IO2, OUTPUT); - serial_interface.begin(Serial); -#endif - the_mesh.startInterface(serial_interface); + #ifdef BLE_PIN_CODE + char dev_name[32+10]; + sprintf(dev_name, "MeshCore-%s", the_mesh.getNodeName()); + serial_interface.begin(dev_name, the_mesh.getBLEPin()); + #else + pinMode(WB_IO2, OUTPUT); + serial_interface.begin(Serial); + #endif + the_mesh.startInterface(serial_interface); + #elif defined(ESP32) SPIFFS.begin(true); the_mesh.begin(SPIFFS, trng); +#elif defined(ESP8285) + SPIFFS.begin(); + the_mesh.begin(SPIFFS, trng); + + #ifdef WIFI_SSID WiFi.begin(WIFI_SSID, WIFI_PWD); serial_interface.begin(TCP_PORT); diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index 2cdf074a..bb7e878e 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -3,7 +3,7 @@ #if defined(NRF52_PLATFORM) #include -#elif defined(ESP32) +#elif defined(ESP32) || defined(ESP8285) || defined(ESP866) #include #endif @@ -92,6 +92,10 @@ #include #include static TechoBoard board; +#elif defined(ESP8285) + #include + #include + static ESP8285Board board; #else #error "need to provide a 'board' object" #endif diff --git a/examples/simple_secure_chat/main.cpp b/examples/simple_secure_chat/main.cpp index 1f854773..09cb54af 100644 --- a/examples/simple_secure_chat/main.cpp +++ b/examples/simple_secure_chat/main.cpp @@ -3,7 +3,7 @@ #if defined(NRF52_PLATFORM) #include -#elif defined(ESP32) +#elif defined(ESP32) || defined(ESP8285) || defined(ESP866) #include #endif diff --git a/platformio.ini b/platformio.ini index e9a615d4..5e8ba9b8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -786,3 +786,44 @@ build_src_filter = ${LilyGo_Techo.build_src_filter} + +<../ lib_deps = ${LilyGo_Techo.lib_deps} densaugeo/base64 @ ~1.4.0 + + +; ----------------- ELRS ESP8285--------------------- + +[esp82xx_base] +platform = espressif8266 +extends = arduino_base +board = esp8285 +build_flags = + ${arduino_base.build_flags} + -D ESP8285 + -D PLATFORM_ESP8266=1 +board_build.ldscript = eagle.flash.1m.ld +build_src_filter = ${arduino_base.build_src_filter} +monitor_filters = esp8266_exception_decoder +upload_resetmethod = nodemcu + +[ELRS_ESP8285_RX] +extends = esp82xx_base +build_flags = + ${esp82xx_base.build_flags} + -D RADIO_CLASS=CustomSX1276 + -D WRAPPER_CLASS=CustomSX1276Wrapper + -D LORA_TX_POWER=20 + -D P_LORA_TX_LED=2 + -D SERIAL_INTERFACE=Serial +build_src_filter = ${esp82xx_base.build_src_filter} + +[env:ELRS_ESP8285_RX_companion_radio_usb] +extends = ELRS_ESP8285_RX +build_flags = + ${ELRS_ESP8285_RX.build_flags} + -D MAX_CONTACTS=100 + -D MAX_GROUP_CHANNELS=1 +build_src_filter = + ${ELRS_ESP8285_RX.build_src_filter} + + + +<../examples/companion_radio/main.cpp> +lib_deps = + ${arduino_base.lib_deps} + densaugeo/base64 @ ~1.4.0 \ No newline at end of file diff --git a/src/helpers/CommonCLI.cpp b/src/helpers/CommonCLI.cpp index 21cd690f..8e29a31d 100644 --- a/src/helpers/CommonCLI.cpp +++ b/src/helpers/CommonCLI.cpp @@ -15,7 +15,11 @@ static uint32_t _atoi(const char* sp) { void CommonCLI::loadPrefs(FILESYSTEM* fs) { if (fs->exists("/node_prefs")) { - File file = fs->open("/node_prefs"); + #if defined(ESP8285) + File file = fs->open("/node_prefs", "r"); + #else + File file = fs->open("/node_prefs"); + #endif if (file) { uint8_t pad[8]; @@ -63,7 +67,11 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) { File file = fs->open("/node_prefs", FILE_O_WRITE); if (file) { file.seek(0); file.truncate(); } #else - File file = fs->open("/node_prefs", "w", true); + #if defined(ESP8285) + File file = fs->open("/node_prefs", "w"); + #else + File file = fs->open("/node_prefs", "w", true); + #endif #endif if (file) { uint8_t pad[8]; diff --git a/src/helpers/ESP8285Board.h b/src/helpers/ESP8285Board.h new file mode 100644 index 00000000..2d98e806 --- /dev/null +++ b/src/helpers/ESP8285Board.h @@ -0,0 +1,103 @@ +#pragma once + +#include +#include + +#if defined(ESP8266) + +#include // For ESP.getResetReason() and ESP.restart() +#include + +#ifndef BD_STARTUP_UNKNOWN + // For ESP8266/ESP8285, if no proper startup reason is available, fall back to a known value. + #define BD_STARTUP_UNKNOWN BD_STARTUP_NORMAL +#endif + + +class ESP8285Board : public mesh::MainBoard { +protected: + uint8_t startup_reason; + +public: + void begin() { + // Determine startup reason using ESP8266 API + String reason = ESP.getResetReason(); + if (reason == "Power on") { + startup_reason = BD_STARTUP_NORMAL; + } else { + // Add more mappings as needed for your enum + startup_reason = BD_STARTUP_UNKNOWN; // Assuming this exists in MainBoard + } + + #ifdef PIN_VBAT_READ + // battery read support + pinMode(PIN_VBAT_READ, INPUT); + adcAttachPin(PIN_VBAT_READ); + #endif + + #ifdef P_LORA_TX_LED + pinMode(P_LORA_TX_LED, OUTPUT); + digitalWrite(P_LORA_TX_LED, LOW); + #endif + + #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL) + Wire.begin(PIN_BOARD_SDA, PIN_BOARD_SCL); + #else + Wire.begin(); + #endif + } + + uint8_t getStartupReason() const override { return startup_reason; } + +#if defined(P_LORA_TX_LED) + void onBeforeTransmit() override { + digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on + } + void onAfterTransmit() override { + digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off + } +#endif + + uint16_t getBattMilliVolts() override { + return 0; // not supported + } + + const char* getManufacturerName() const override { + return "Generic ESP8285"; + } + + void reboot() override { + ESP.restart(); // ESP8266 reboot function + } +}; + +class ESP8285RTCClock : public mesh::RTCClock { +public: + ESP8285RTCClock() { } + void begin() { + String reason = ESP.getResetReason(); + if (reason == "Power on") { + // Initialize with a default time on power-on + struct timeval tv; + tv.tv_sec = 1715770351; // 15 May 2024, 8:50pm + tv.tv_usec = 0; + settimeofday(&tv, NULL); + } + // On other resets, assume time persists unless synced externally + } + + uint32_t getCurrentTime() override { + time_t now; + time(&now); + return now; + } + + void setCurrentTime(uint32_t time) override { + struct timeval tv; + tv.tv_sec = time; + tv.tv_usec = 0; + settimeofday(&tv, NULL); + } +}; + +#endif diff --git a/src/helpers/IdentityStore.cpp b/src/helpers/IdentityStore.cpp index 3b44eb4a..984f5e80 100644 --- a/src/helpers/IdentityStore.cpp +++ b/src/helpers/IdentityStore.cpp @@ -5,7 +5,11 @@ bool IdentityStore::load(const char *name, mesh::LocalIdentity& id) { char filename[40]; sprintf(filename, "%s/%s.id", _dir, name); if (_fs->exists(filename)) { +#if defined(ESP8285) + File file = _fs->open(filename, "r"); +#else File file = _fs->open(filename); +#endif if (file) { loaded = id.readFrom(file); file.close(); @@ -19,7 +23,11 @@ bool IdentityStore::load(const char *name, mesh::LocalIdentity& id, char display char filename[40]; sprintf(filename, "%s/%s.id", _dir, name); if (_fs->exists(filename)) { +#if defined(ESP8285) + File file = _fs->open(filename, "r"); +#else File file = _fs->open(filename); +#endif if (file) { loaded = id.readFrom(file); @@ -41,6 +49,8 @@ bool IdentityStore::save(const char *name, const mesh::LocalIdentity& id) { #if defined(NRF52_PLATFORM) File file = _fs->open(filename, FILE_O_WRITE); if (file) { file.seek(0); file.truncate(); } +#elif defined(ESP8285) + File file = _fs->open(filename, "w"); #else File file = _fs->open(filename, "w", true); #endif @@ -61,6 +71,8 @@ bool IdentityStore::save(const char *name, const mesh::LocalIdentity& id, const #if defined(NRF52_PLATFORM) File file = _fs->open(filename, FILE_O_WRITE); if (file) { file.seek(0); file.truncate(); } +#elif defined(ESP8285) + File file = _fs->open(filename, "w"); #else File file = _fs->open(filename, "w", true); #endif diff --git a/src/helpers/IdentityStore.h b/src/helpers/IdentityStore.h index 2a5363ea..5953aadd 100644 --- a/src/helpers/IdentityStore.h +++ b/src/helpers/IdentityStore.h @@ -1,6 +1,6 @@ #pragma once -#if defined(ESP32) +#if defined(ESP32) || defined(ESP8266) #include #define FILESYSTEM fs::FS #elif defined(NRF52_PLATFORM) diff --git a/src/helpers/RadioLibWrappers.cpp b/src/helpers/RadioLibWrappers.cpp index 8d133ccd..c623e36a 100644 --- a/src/helpers/RadioLibWrappers.cpp +++ b/src/helpers/RadioLibWrappers.cpp @@ -13,7 +13,7 @@ static volatile uint8_t state = STATE_IDLE; // this function is called when a complete packet // is transmitted by the module static -#if defined(ESP8266) || defined(ESP32) +#if defined(ESP8266) || defined(ESP32) || defined(ESP8285) ICACHE_RAM_ATTR #endif void setFlag(void) { diff --git a/src/helpers/esp8285/SerialWifiInterface.cpp b/src/helpers/esp8285/SerialWifiInterface.cpp new file mode 100644 index 00000000..e7dc055e --- /dev/null +++ b/src/helpers/esp8285/SerialWifiInterface.cpp @@ -0,0 +1,93 @@ +#include "SerialWifiInterface.h" +#include + +void SerialWifiInterface::begin(int port) { + // wifi setup is handled outside of this class, only starts the server + server.begin(port); +} + +// ---------- public methods +void SerialWifiInterface::enable() { + if (_isEnabled) return; + + _isEnabled = true; + clearBuffers(); +} + +void SerialWifiInterface::disable() { + _isEnabled = false; +} + +size_t SerialWifiInterface::writeFrame(const uint8_t src[], size_t len) { + if (len > MAX_FRAME_SIZE) { + WIFI_DEBUG_PRINTLN("writeFrame(), frame too big, len=%d\n", len); + return 0; + } + + if (deviceConnected && len > 0) { + if (send_queue_len >= FRAME_QUEUE_SIZE) { + WIFI_DEBUG_PRINTLN("writeFrame(), send_queue is full!"); + return 0; + } + + send_queue[send_queue_len].len = len; // add to send queue + memcpy(send_queue[send_queue_len].buf, src, len); + send_queue_len++; + + return len; + } + return 0; +} + +bool SerialWifiInterface::isWriteBusy() const { + return false; +} + +size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) { + if (!client) client = server.available(); + + if (client.connected()) { + if (!deviceConnected) { + WIFI_DEBUG_PRINTLN("Got connection"); + deviceConnected = true; + } + } else { + if (deviceConnected) { + deviceConnected = false; + WIFI_DEBUG_PRINTLN("Disconnected"); + } + } + + if (deviceConnected) { + if (send_queue_len > 0) { // first, check send queue + + _last_write = millis(); + int len = send_queue[0].len; + + uint8_t pkt[3+len]; // use same header as serial interface so client can delimit frames + pkt[0] = '>'; + pkt[1] = (len & 0xFF); // LSB + pkt[2] = (len >> 8); // MSB + memcpy(&pkt[3], send_queue[0].buf, send_queue[0].len); + client.write(pkt, 3 + len); + send_queue_len--; + for (int i = 0; i < send_queue_len; i++) { // delete top item from queue + send_queue[i] = send_queue[i + 1]; + } + } else { + int len = client.available(); + if (len > 0) { + uint8_t buf[MAX_FRAME_SIZE + 4]; + client.readBytes(buf, len); + memcpy(dest, buf+3, len-3); // remove header (don't even check ... problems are on the other dir) + return len-3; + } + } + } + + return 0; +} + +bool SerialWifiInterface::isConnected() const { + return deviceConnected; //pServer != NULL && pServer->getConnectedCount() > 0; +} \ No newline at end of file diff --git a/src/helpers/esp8285/SerialWifiInterface.h b/src/helpers/esp8285/SerialWifiInterface.h new file mode 100644 index 00000000..2b6c6edd --- /dev/null +++ b/src/helpers/esp8285/SerialWifiInterface.h @@ -0,0 +1,59 @@ +#pragma once + +#include "../BaseSerialInterface.h" +#include + +class SerialWifiInterface : public BaseSerialInterface { + bool deviceConnected; + bool _isEnabled; + unsigned long _last_write; + unsigned long adv_restart_time; + + WiFiServer server; + WiFiClient client; + + struct Frame { + uint8_t len; + uint8_t buf[MAX_FRAME_SIZE]; + }; + + #define FRAME_QUEUE_SIZE 4 + int recv_queue_len; + Frame recv_queue[FRAME_QUEUE_SIZE]; + int send_queue_len; + Frame send_queue[FRAME_QUEUE_SIZE]; + + void clearBuffers() { recv_queue_len = 0; send_queue_len = 0; } + +protected: + +public: + SerialWifiInterface() : server(WiFiServer()), client(WiFiClient()) { + deviceConnected = false; + _isEnabled = false; + _last_write = 0; + send_queue_len = recv_queue_len = 0; + } + + void begin(int port); + + // BaseSerialInterface methods + void enable() override; + void disable() override; + bool isEnabled() const override { return _isEnabled; } + + bool isConnected() const override; + bool isWriteBusy() const override; + + size_t writeFrame(const uint8_t src[], size_t len) override; + size_t checkRecvFrame(uint8_t dest[]) override; +}; + +#if WIFI_DEBUG_LOGGING && ARDUINO + #include + #define WIFI_DEBUG_PRINT(F, ...) Serial.printf("WiFi: " F, ##__VA_ARGS__) + #define WIFI_DEBUG_PRINTLN(F, ...) Serial.printf("WiFi: " F "\n", ##__VA_ARGS__) +#else + #define WIFI_DEBUG_PRINT(...) {} + #define WIFI_DEBUG_PRINTLN(...) {} +#endif From aad96394b838cc691bed431b64d0e37672be1c4d Mon Sep 17 00:00:00 2001 From: frogmane Date: Sun, 9 Mar 2025 12:30:42 -0400 Subject: [PATCH 2/7] compiles --- examples/companion_radio/main.cpp | 17 ++++++++++------- platformio.ini | 16 ++++++++++++---- src/helpers/ESP8285Board.h | 14 +++++++------- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 50ffe041..840e4e01 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -1253,15 +1253,15 @@ class MyMesh : public BaseChatMesh { #endif #if defined(NRF52_PLATFORM) -RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); -#elif defined(LILYGO_TLORA) -SPIClass spi; -RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi); + RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); +#elif defined(LILYGO_TLORA) || defined(ESP8285) + SPIClass spi; + RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi); #elif defined(P_LORA_SCLK) -SPIClass spi; -RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi); + SPIClass spi; + RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi); #else -RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); + RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY); #endif StdRNG fast_rng; SimpleMeshTables tables; @@ -1273,6 +1273,7 @@ void halt() { void setup() { Serial.begin(115200); + board.begin(); #ifdef SX126X_DIO3_TCXO_VOLTAGE @@ -1284,6 +1285,8 @@ void setup() { #if defined(NRF52_PLATFORM) SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI); SPI.begin(); +#elif defined(ESP8285) + spi.begin(); #elif defined(P_LORA_SCLK) spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI); #endif diff --git a/platformio.ini b/platformio.ini index 5e8ba9b8..3cd36c6e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -793,12 +793,11 @@ lib_deps = [esp82xx_base] platform = espressif8266 extends = arduino_base -board = esp8285 +board = esp8285-8285 build_flags = ${arduino_base.build_flags} -D ESP8285 -D PLATFORM_ESP8266=1 -board_build.ldscript = eagle.flash.1m.ld build_src_filter = ${arduino_base.build_src_filter} monitor_filters = esp8266_exception_decoder upload_resetmethod = nodemcu @@ -810,15 +809,24 @@ build_flags = -D RADIO_CLASS=CustomSX1276 -D WRAPPER_CLASS=CustomSX1276Wrapper -D LORA_TX_POWER=20 - -D P_LORA_TX_LED=2 -D SERIAL_INTERFACE=Serial + -D P_LORA_DIO_0=4 + -D P_LORA_DIO_1=5 + -D P_LORA_NSS=15 + -D P_LORA_RESET=2 + -D P_LORA_SCLK=14 + -D P_LORA_MISO=12 + -D P_LORA_MOSI=13 + -D PIN_RX=3 + -D PIN_TX=1 + -D PIN_LED_BUILTIN=16 build_src_filter = ${esp82xx_base.build_src_filter} [env:ELRS_ESP8285_RX_companion_radio_usb] extends = ELRS_ESP8285_RX build_flags = ${ELRS_ESP8285_RX.build_flags} - -D MAX_CONTACTS=100 + -D MAX_CONTACTS=10 -D MAX_GROUP_CHANNELS=1 build_src_filter = ${ELRS_ESP8285_RX.build_src_filter} diff --git a/src/helpers/ESP8285Board.h b/src/helpers/ESP8285Board.h index 2d98e806..d793c4e8 100644 --- a/src/helpers/ESP8285Board.h +++ b/src/helpers/ESP8285Board.h @@ -35,9 +35,9 @@ class ESP8285Board : public mesh::MainBoard { adcAttachPin(PIN_VBAT_READ); #endif - #ifdef P_LORA_TX_LED - pinMode(P_LORA_TX_LED, OUTPUT); - digitalWrite(P_LORA_TX_LED, LOW); + #ifdef PIN_LED_BUILTIN + pinMode(PIN_LED_BUILTIN, OUTPUT); + digitalWrite(PIN_LED_BUILTIN, LOW); #endif #if defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL) @@ -49,12 +49,12 @@ class ESP8285Board : public mesh::MainBoard { uint8_t getStartupReason() const override { return startup_reason; } -#if defined(P_LORA_TX_LED) +#if defined(PIN_LED_BUILTIN) void onBeforeTransmit() override { - digitalWrite(P_LORA_TX_LED, HIGH); // turn TX LED on + digitalWrite(PIN_LED_BUILTIN, HIGH); // turn TX LED on } void onAfterTransmit() override { - digitalWrite(P_LORA_TX_LED, LOW); // turn TX LED off + digitalWrite(PIN_LED_BUILTIN, LOW); // turn TX LED off } #endif @@ -63,7 +63,7 @@ class ESP8285Board : public mesh::MainBoard { } const char* getManufacturerName() const override { - return "Generic ESP8285"; + return "Generic ESP8285 ELRS Receiver"; } void reboot() override { From 854eb8af5350124775041a7fdbd7468c81cbfb7d Mon Sep 17 00:00:00 2001 From: frogmane Date: Sun, 9 Mar 2025 12:42:44 -0400 Subject: [PATCH 3/7] IT WORKS --- boards/esp8285-8285.json | 3 +-- platformio.ini | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/boards/esp8285-8285.json b/boards/esp8285-8285.json index 640c0a26..98481fbb 100644 --- a/boards/esp8285-8285.json +++ b/boards/esp8285-8285.json @@ -2,8 +2,7 @@ "comment": "esp8285 variant for ExpressLRS that uses variant=esp8285 instead of variant=generic", "build": { "arduino": { - "ldscript": "eagle.flash.1m256.ld", - "memory_type": "qio_qspi" + "ldscript": "eagle.flash.1m256.ld" }, "core": "esp8266", "extra_flags": "-DESP8266 -DESP8285 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01", diff --git a/platformio.ini b/platformio.ini index 3cd36c6e..d51f78be 100644 --- a/platformio.ini +++ b/platformio.ini @@ -19,7 +19,7 @@ lib_deps = adafruit/RTClib @ ^2.1.3 melopero/Melopero RV3028 @ ^1.1.0 build_flags = -w -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1 - -D LORA_FREQ=867.5 + -D LORA_FREQ=915.2 -D LORA_BW=250 -D LORA_SF=10 build_src_filter = +<*.cpp> + @@ -826,7 +826,7 @@ build_src_filter = ${esp82xx_base.build_src_filter} extends = ELRS_ESP8285_RX build_flags = ${ELRS_ESP8285_RX.build_flags} - -D MAX_CONTACTS=10 + -D MAX_CONTACTS=25 -D MAX_GROUP_CHANNELS=1 build_src_filter = ${ELRS_ESP8285_RX.build_src_filter} From 26e7635c4a98301342052639e60672701bf32075 Mon Sep 17 00:00:00 2001 From: frogmane Date: Sun, 9 Mar 2025 14:20:22 -0400 Subject: [PATCH 4/7] repeater + trying to get serialwifi to work --- boards/esp8285-8285.json | 2 +- examples/companion_radio/main.cpp | 6 +-- examples/simple_repeater/main.cpp | 22 +++++++++-- examples/simple_secure_chat/main.cpp | 4 +- platformio.ini | 41 ++++++++++++++++++++- src/helpers/esp8285/SerialWifiInterface.cpp | 2 +- src/helpers/esp8285/SerialWifiInterface.h | 4 +- 7 files changed, 67 insertions(+), 14 deletions(-) diff --git a/boards/esp8285-8285.json b/boards/esp8285-8285.json index 98481fbb..578af0ad 100644 --- a/boards/esp8285-8285.json +++ b/boards/esp8285-8285.json @@ -1,5 +1,5 @@ { - "comment": "esp8285 variant for ExpressLRS that uses variant=esp8285 instead of variant=generic", + "comment": "From ExpressLRS project, https://github.com/ExpressLRS/ExpressLRS/blob/master/src/boards/esp8285-8285.json: esp8285 variant for ExpressLRS that uses variant=esp8285 instead of variant=generic", "build": { "arduino": { "ldscript": "eagle.flash.1m256.ld" diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 840e4e01..96459053 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -1231,11 +1231,11 @@ class MyMesh : public BaseChatMesh { #endif #elif defined(ESP8285) #ifdef WIFI_SSID - #include - SerialWifiInterface serial_interface; #ifndef TCP_PORT #define TCP_PORT 5000 #endif + #include + SerialWifiInterface serial_interface(TCP_PORT); // Pass TCP_PORT to the constructor #else #include ArduinoSerialInterface serial_interface; @@ -1273,7 +1273,7 @@ void halt() { void setup() { Serial.begin(115200); - + board.begin(); #ifdef SX126X_DIO3_TCXO_VOLTAGE diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index bb7e878e..9a137fbe 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -3,8 +3,10 @@ #if defined(NRF52_PLATFORM) #include -#elif defined(ESP32) || defined(ESP8285) || defined(ESP866) +#elif defined(ESP32) #include +#elif defined(ESP8285) || defined(ESP866) + #include #endif #define RADIOLIB_STATIC_ONLY 1 @@ -224,6 +226,8 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { File openAppend(const char* fname) { #if defined(NRF52_PLATFORM) return _fs->open(fname, FILE_O_WRITE); + #elif defined(ESP8285) + return _fs->open(fname, "a"); #else return _fs->open(fname, "a", true); #endif @@ -557,7 +561,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { bool formatFileSystem() override { #if defined(NRF52_PLATFORM) return InternalFS.format(); -#elif defined(ESP32) +#elif defined(ESP32) || defined(ESP8285) return SPIFFS.format(); #else #error "need to implement file system erase" @@ -589,7 +593,11 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { } void dumpLogFile() override { - File f = _fs->open(PACKET_LOG_FILE); + #if defined(ESP8285) + File f = _fs->open(PACKET_LOG_FILE, "r"); + #else + File f = _fs->open(PACKET_LOG_FILE); + #endif if (f) { while (f.available()) { int c = f.read(); @@ -623,7 +631,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks { #if defined(NRF52_PLATFORM) RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, SPI); -#elif defined(LILYGO_TLORA) +#elif defined(LILYGO_TLORA) || defined(ESP8285) SPIClass spi; RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_0, P_LORA_RESET, P_LORA_DIO_1, spi); #elif defined(P_LORA_SCLK) @@ -669,6 +677,8 @@ void setup() { #if defined(NRF52_PLATFORM) SPI.setPins(P_LORA_MISO, P_LORA_SCLK, P_LORA_MOSI); SPI.begin(); +#elif defined(ESP8285) + spi.begin(); #elif defined(P_LORA_SCLK) spi.begin(P_LORA_SCLK, P_LORA_MISO, P_LORA_MOSI); #endif @@ -701,6 +711,10 @@ void setup() { SPIFFS.begin(true); fs = &SPIFFS; IdentityStore store(SPIFFS, "/identity"); +#elif defined(ESP8285) + SPIFFS.begin(); + fs = &SPIFFS; + IdentityStore store(SPIFFS, "/identity"); #else #error "need to define filesystem" #endif diff --git a/examples/simple_secure_chat/main.cpp b/examples/simple_secure_chat/main.cpp index 09cb54af..7076fed3 100644 --- a/examples/simple_secure_chat/main.cpp +++ b/examples/simple_secure_chat/main.cpp @@ -3,8 +3,10 @@ #if defined(NRF52_PLATFORM) #include -#elif defined(ESP32) || defined(ESP8285) || defined(ESP866) +#elif defined(ESP32) #include +#elif defined(ESP8285) || defined(ESP866) + #include #endif #define RADIOLIB_STATIC_ONLY 1 diff --git a/platformio.ini b/platformio.ini index d51f78be..e6c66c4f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -802,6 +802,7 @@ build_src_filter = ${arduino_base.build_src_filter} monitor_filters = esp8266_exception_decoder upload_resetmethod = nodemcu +; -- pin defs from https://github.com/ExpressLRS/targets/blob/master/RX/Generic%20900.json [ELRS_ESP8285_RX] extends = esp82xx_base build_flags = @@ -826,7 +827,7 @@ build_src_filter = ${esp82xx_base.build_src_filter} extends = ELRS_ESP8285_RX build_flags = ${ELRS_ESP8285_RX.build_flags} - -D MAX_CONTACTS=25 + -D MAX_CONTACTS=50 -D MAX_GROUP_CHANNELS=1 build_src_filter = ${ELRS_ESP8285_RX.build_src_filter} @@ -834,4 +835,40 @@ build_src_filter = +<../examples/companion_radio/main.cpp> lib_deps = ${arduino_base.lib_deps} - densaugeo/base64 @ ~1.4.0 \ No newline at end of file + densaugeo/base64 @ ~1.4.0 + +[env:ELRS_ESP8285_RX_repeater] +extends = ELRS_ESP8285_RX +build_flags = + ${ELRS_ESP8285_RX.build_flags} + -D ADVERT_NAME="\"ELRSRX Repeater\"" + -D ADVERT_LAT=-37.0 + -D ADVERT_LON=145.0 + -D ADMIN_PASSWORD="\"password\"" +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = + ${ELRS_ESP8285_RX.build_src_filter} + +<../examples/simple_repeater/main.cpp> + +[env:ELRS_ESP8285_RX_companion_radio_wifi] +extends = ELRS_ESP8285_RX +build_flags = + ${ELRS_ESP8285_RX.build_flags} + -D MAX_CONTACTS=5 + -D MAX_GROUP_CHANNELS=1 + -D WIFI_DEBUG_LOGGING=1 + -D WIFI_SSID="\"myssid\"" + -D WIFI_PWD="\"mypwd\"" +; -D ENABLE_PRIVATE_KEY_IMPORT=1 +; -D ENABLE_PRIVATE_KEY_EXPORT=1 +; -D MESH_PACKET_LOGGING=1 +; -D MESH_DEBUG=1 +build_src_filter = + ${ELRS_ESP8285_RX.build_src_filter} + + + + + +<../examples/companion_radio/main.cpp> +lib_deps = + ${ELRS_ESP8285_RX.lib_deps} + densaugeo/base64 @ ~1.4.0 \ No newline at end of file diff --git a/src/helpers/esp8285/SerialWifiInterface.cpp b/src/helpers/esp8285/SerialWifiInterface.cpp index e7dc055e..ec525f80 100644 --- a/src/helpers/esp8285/SerialWifiInterface.cpp +++ b/src/helpers/esp8285/SerialWifiInterface.cpp @@ -1,5 +1,5 @@ #include "SerialWifiInterface.h" -#include +#include void SerialWifiInterface::begin(int port) { // wifi setup is handled outside of this class, only starts the server diff --git a/src/helpers/esp8285/SerialWifiInterface.h b/src/helpers/esp8285/SerialWifiInterface.h index 2b6c6edd..4e3333a9 100644 --- a/src/helpers/esp8285/SerialWifiInterface.h +++ b/src/helpers/esp8285/SerialWifiInterface.h @@ -1,7 +1,7 @@ #pragma once #include "../BaseSerialInterface.h" -#include +#include class SerialWifiInterface : public BaseSerialInterface { bool deviceConnected; @@ -28,7 +28,7 @@ class SerialWifiInterface : public BaseSerialInterface { protected: public: - SerialWifiInterface() : server(WiFiServer()), client(WiFiClient()) { + SerialWifiInterface(uint16_t port) : server(port), client(WiFiClient()) { deviceConnected = false; _isEnabled = false; _last_write = 0; From 7cbd00ee98f29724536262e0a3a854a5c521b579 Mon Sep 17 00:00:00 2001 From: frogmane Date: Sun, 9 Mar 2025 15:24:22 -0400 Subject: [PATCH 5/7] esp8285 cant handle 50 contacts --- platformio.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index e6c66c4f..7346f1d1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -827,7 +827,7 @@ build_src_filter = ${esp82xx_base.build_src_filter} extends = ELRS_ESP8285_RX build_flags = ${ELRS_ESP8285_RX.build_flags} - -D MAX_CONTACTS=50 + -D MAX_CONTACTS=25 ; crash = 50, 40, -D MAX_GROUP_CHANNELS=1 build_src_filter = ${ELRS_ESP8285_RX.build_src_filter} @@ -855,7 +855,7 @@ build_src_filter = extends = ELRS_ESP8285_RX build_flags = ${ELRS_ESP8285_RX.build_flags} - -D MAX_CONTACTS=5 + -D MAX_CONTACTS=5 ; still doesn't work? -D MAX_GROUP_CHANNELS=1 -D WIFI_DEBUG_LOGGING=1 -D WIFI_SSID="\"myssid\"" From 48678b9b3686bd24969bc01ba2f96aec39fe936c Mon Sep 17 00:00:00 2001 From: frogmane Date: Mon, 10 Mar 2025 14:54:06 -0400 Subject: [PATCH 6/7] limit to usb companion + repeater --- platformio.ini | 24 +----- src/helpers/esp8285/SerialWifiInterface.cpp | 93 --------------------- src/helpers/esp8285/SerialWifiInterface.h | 59 ------------- 3 files changed, 1 insertion(+), 175 deletions(-) delete mode 100644 src/helpers/esp8285/SerialWifiInterface.cpp delete mode 100644 src/helpers/esp8285/SerialWifiInterface.h diff --git a/platformio.ini b/platformio.ini index 7346f1d1..aaa8e6e9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -849,26 +849,4 @@ build_flags = ; -D MESH_DEBUG=1 build_src_filter = ${ELRS_ESP8285_RX.build_src_filter} - +<../examples/simple_repeater/main.cpp> - -[env:ELRS_ESP8285_RX_companion_radio_wifi] -extends = ELRS_ESP8285_RX -build_flags = - ${ELRS_ESP8285_RX.build_flags} - -D MAX_CONTACTS=5 ; still doesn't work? - -D MAX_GROUP_CHANNELS=1 - -D WIFI_DEBUG_LOGGING=1 - -D WIFI_SSID="\"myssid\"" - -D WIFI_PWD="\"mypwd\"" -; -D ENABLE_PRIVATE_KEY_IMPORT=1 -; -D ENABLE_PRIVATE_KEY_EXPORT=1 -; -D MESH_PACKET_LOGGING=1 -; -D MESH_DEBUG=1 -build_src_filter = - ${ELRS_ESP8285_RX.build_src_filter} - + - + - +<../examples/companion_radio/main.cpp> -lib_deps = - ${ELRS_ESP8285_RX.lib_deps} - densaugeo/base64 @ ~1.4.0 \ No newline at end of file + +<../examples/simple_repeater/main.cpp> \ No newline at end of file diff --git a/src/helpers/esp8285/SerialWifiInterface.cpp b/src/helpers/esp8285/SerialWifiInterface.cpp deleted file mode 100644 index ec525f80..00000000 --- a/src/helpers/esp8285/SerialWifiInterface.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "SerialWifiInterface.h" -#include - -void SerialWifiInterface::begin(int port) { - // wifi setup is handled outside of this class, only starts the server - server.begin(port); -} - -// ---------- public methods -void SerialWifiInterface::enable() { - if (_isEnabled) return; - - _isEnabled = true; - clearBuffers(); -} - -void SerialWifiInterface::disable() { - _isEnabled = false; -} - -size_t SerialWifiInterface::writeFrame(const uint8_t src[], size_t len) { - if (len > MAX_FRAME_SIZE) { - WIFI_DEBUG_PRINTLN("writeFrame(), frame too big, len=%d\n", len); - return 0; - } - - if (deviceConnected && len > 0) { - if (send_queue_len >= FRAME_QUEUE_SIZE) { - WIFI_DEBUG_PRINTLN("writeFrame(), send_queue is full!"); - return 0; - } - - send_queue[send_queue_len].len = len; // add to send queue - memcpy(send_queue[send_queue_len].buf, src, len); - send_queue_len++; - - return len; - } - return 0; -} - -bool SerialWifiInterface::isWriteBusy() const { - return false; -} - -size_t SerialWifiInterface::checkRecvFrame(uint8_t dest[]) { - if (!client) client = server.available(); - - if (client.connected()) { - if (!deviceConnected) { - WIFI_DEBUG_PRINTLN("Got connection"); - deviceConnected = true; - } - } else { - if (deviceConnected) { - deviceConnected = false; - WIFI_DEBUG_PRINTLN("Disconnected"); - } - } - - if (deviceConnected) { - if (send_queue_len > 0) { // first, check send queue - - _last_write = millis(); - int len = send_queue[0].len; - - uint8_t pkt[3+len]; // use same header as serial interface so client can delimit frames - pkt[0] = '>'; - pkt[1] = (len & 0xFF); // LSB - pkt[2] = (len >> 8); // MSB - memcpy(&pkt[3], send_queue[0].buf, send_queue[0].len); - client.write(pkt, 3 + len); - send_queue_len--; - for (int i = 0; i < send_queue_len; i++) { // delete top item from queue - send_queue[i] = send_queue[i + 1]; - } - } else { - int len = client.available(); - if (len > 0) { - uint8_t buf[MAX_FRAME_SIZE + 4]; - client.readBytes(buf, len); - memcpy(dest, buf+3, len-3); // remove header (don't even check ... problems are on the other dir) - return len-3; - } - } - } - - return 0; -} - -bool SerialWifiInterface::isConnected() const { - return deviceConnected; //pServer != NULL && pServer->getConnectedCount() > 0; -} \ No newline at end of file diff --git a/src/helpers/esp8285/SerialWifiInterface.h b/src/helpers/esp8285/SerialWifiInterface.h deleted file mode 100644 index 4e3333a9..00000000 --- a/src/helpers/esp8285/SerialWifiInterface.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include "../BaseSerialInterface.h" -#include - -class SerialWifiInterface : public BaseSerialInterface { - bool deviceConnected; - bool _isEnabled; - unsigned long _last_write; - unsigned long adv_restart_time; - - WiFiServer server; - WiFiClient client; - - struct Frame { - uint8_t len; - uint8_t buf[MAX_FRAME_SIZE]; - }; - - #define FRAME_QUEUE_SIZE 4 - int recv_queue_len; - Frame recv_queue[FRAME_QUEUE_SIZE]; - int send_queue_len; - Frame send_queue[FRAME_QUEUE_SIZE]; - - void clearBuffers() { recv_queue_len = 0; send_queue_len = 0; } - -protected: - -public: - SerialWifiInterface(uint16_t port) : server(port), client(WiFiClient()) { - deviceConnected = false; - _isEnabled = false; - _last_write = 0; - send_queue_len = recv_queue_len = 0; - } - - void begin(int port); - - // BaseSerialInterface methods - void enable() override; - void disable() override; - bool isEnabled() const override { return _isEnabled; } - - bool isConnected() const override; - bool isWriteBusy() const override; - - size_t writeFrame(const uint8_t src[], size_t len) override; - size_t checkRecvFrame(uint8_t dest[]) override; -}; - -#if WIFI_DEBUG_LOGGING && ARDUINO - #include - #define WIFI_DEBUG_PRINT(F, ...) Serial.printf("WiFi: " F, ##__VA_ARGS__) - #define WIFI_DEBUG_PRINTLN(F, ...) Serial.printf("WiFi: " F "\n", ##__VA_ARGS__) -#else - #define WIFI_DEBUG_PRINT(...) {} - #define WIFI_DEBUG_PRINTLN(...) {} -#endif From a111f32839dd994dd0a079ff6cc99465e8f7deca Mon Sep 17 00:00:00 2001 From: frogmane Date: Mon, 10 Mar 2025 23:05:33 -0400 Subject: [PATCH 7/7] change freq back to standard --- examples/companion_radio/main.cpp | 2 +- platformio.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/companion_radio/main.cpp b/examples/companion_radio/main.cpp index 96459053..bf86e162 100644 --- a/examples/companion_radio/main.cpp +++ b/examples/companion_radio/main.cpp @@ -3,7 +3,7 @@ #if defined(NRF52_PLATFORM) #include -#elif defined(ESP32) +#elif defined(ESP32) #include #elif defined(ESP8285) || defined(ESP866) #include diff --git a/platformio.ini b/platformio.ini index aaa8e6e9..71884af7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -19,7 +19,7 @@ lib_deps = adafruit/RTClib @ ^2.1.3 melopero/Melopero RV3028 @ ^1.1.0 build_flags = -w -DNDEBUG -DRADIOLIB_STATIC_ONLY=1 -DRADIOLIB_GODMODE=1 - -D LORA_FREQ=915.2 + -D LORA_FREQ=867.5 -D LORA_BW=250 -D LORA_SF=10 build_src_filter = +<*.cpp> +