Compare commits
10 Commits
8db47d4d01
...
a57b3bc6de
| Author | SHA1 | Date | |
|---|---|---|---|
| a57b3bc6de | |||
|
|
b3b6cd4302 | ||
|
|
7e56611fe6 | ||
|
|
56c1a6b881 | ||
|
|
79cb2d49e8 | ||
|
|
d8c925769d | ||
|
|
300676e5ae | ||
|
|
d49c55a843 | ||
|
|
85d8fc7f78 | ||
|
|
949c13c7b1 |
46
Boards.h
46
Boards.h
@@ -122,6 +122,8 @@
|
||||
#define MODEL_FE 0xFE // Homebrew board, max 17dBm output power
|
||||
#define MODEL_FF 0xFF // Homebrew board, max 14dBm output power
|
||||
|
||||
#define BOARD_MESHADVENTURER_S3 0xF2
|
||||
|
||||
#if defined(__AVR_ATmega1284P__)
|
||||
#define PLATFORM PLATFORM_AVR
|
||||
#define MCU_VARIANT MCU_1284P
|
||||
@@ -449,6 +451,50 @@
|
||||
const int pin_miso = 11;
|
||||
const int pin_sclk = 9;
|
||||
|
||||
#elif BOARD_MODEL == BOARD_MESHADVENTURER_S3
|
||||
#define IS_ESP32S3 true
|
||||
#define HAS_DISPLAY true
|
||||
#define HAS_NP true
|
||||
#define HAS_BLUETOOTH false
|
||||
#define HAS_BLE true
|
||||
#define HAS_WIFI true
|
||||
#define HAS_CONSOLE true
|
||||
#define HAS_EEPROM true
|
||||
#define HAS_BUSY true
|
||||
#define HAS_INPUT true
|
||||
#define HAS_TCXO true
|
||||
#define MODEM SX1262
|
||||
#define DIO2_AS_RF_SWITCH false
|
||||
#define HAS_RF_SWITCH_RX_TX true
|
||||
#define HAS_LORA_LNA true
|
||||
#define LORA_LNA_GAIN 30
|
||||
#define LORA_LNA_GVT 14
|
||||
#define PA_MAX_OUTPUT 22
|
||||
|
||||
const int pin_cs = 39;
|
||||
const int pin_sclk = 38;
|
||||
const int pin_miso = 40;
|
||||
const int pin_mosi = 18;
|
||||
const int pin_busy = 7;
|
||||
const int pin_reset = 43;
|
||||
const int pin_dio = 15;
|
||||
const int pin_txen = 9;
|
||||
const int pin_rxen = 8;
|
||||
const int pin_tcxo_enable = -1;
|
||||
|
||||
const int pin_btn_usr1 = 4;
|
||||
const int pin_np = 48;
|
||||
|
||||
#if HAS_NP == false
|
||||
#if defined(EXTERNAL_LEDS)
|
||||
const int pin_led_rx = 48;
|
||||
const int pin_led_tx = 48;
|
||||
#else
|
||||
const int pin_led_rx = 48;
|
||||
const int pin_led_tx = 48;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif BOARD_MODEL == BOARD_RNODE_NG_20
|
||||
#define HAS_DISPLAY true
|
||||
#define HAS_BLUETOOTH true
|
||||
|
||||
75
BoundaryConfig.h
Normal file → Executable file
75
BoundaryConfig.h
Normal file → Executable file
@@ -1,7 +1,10 @@
|
||||
// Copyright (C) 2026, Boundary Mode Extension
|
||||
// Based on microReticulum_Firmware by Mark Qvist
|
||||
//
|
||||
// BoundaryConfig.h — Captive-portal web configuration for Boundary Mode.
|
||||
// BoundaryConfig.h — Captive-portal web configuration for the legacy
|
||||
// "Boundary Mode" path. This should be renamed to "Transport Mode"
|
||||
// together with the rest of the boundary-mode terminology. In this fork,
|
||||
// transport/boundary mode is the only intended mode of operation.
|
||||
// When triggered (first boot with no config, or button hold >5s),
|
||||
// the device starts a WiFi AP with a web form for all settings:
|
||||
// WiFi STA credentials, TCP backbone params, LoRa radio params,
|
||||
@@ -59,6 +62,16 @@ static const char* const BW_OPTIONS_LABELS[] PROGMEM = {
|
||||
};
|
||||
static const int BW_OPTIONS_COUNT = sizeof(BW_OPTIONS_HZ) / sizeof(BW_OPTIONS_HZ[0]);
|
||||
|
||||
static uint8_t config_default_display_rotation() {
|
||||
#if BOARD_MODEL == BOARD_LORA32_V2_1 || BOARD_MODEL == BOARD_TBEAM || BOARD_MODEL == BOARD_RAK4631
|
||||
return 0;
|
||||
#elif BOARD_MODEL == BOARD_HELTEC32_V2 || BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == BOARD_HELTEC32_V4 || BOARD_MODEL == BOARD_HELTEC_T114 || BOARD_MODEL == BOARD_TBEAM_S_V1
|
||||
return 1;
|
||||
#else
|
||||
return 3;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ─── HTML Page Generation ────────────────────────────────────────────────────
|
||||
|
||||
static void config_send_html() {
|
||||
@@ -87,10 +100,10 @@ static void config_send_html() {
|
||||
if (cur_txp == 0xFF) cur_txp = PA_MAX_OUTPUT; // Default to board max
|
||||
|
||||
// Default frequency if not set
|
||||
if (cur_freq == 0) cur_freq = 914875000; // 914.875 MHz default
|
||||
if (cur_freq == 0) cur_freq = 868825000; // 914.875 MHz default
|
||||
if (cur_bw == 0) cur_bw = 125000; // 125 kHz default
|
||||
if (cur_sf == 0) cur_sf = 10; // SF10 default
|
||||
if (cur_cr < 5 || cur_cr > 8) cur_cr = 5; // CR 4/5 default
|
||||
if (cur_cr < 5 || cur_cr > 8) cur_cr = 7; // CR 4/5 default
|
||||
|
||||
// Build the HTML page
|
||||
String html = F(
|
||||
@@ -221,9 +234,9 @@ static void config_send_html() {
|
||||
}
|
||||
html += F("</select>");
|
||||
|
||||
// Spreading Factor — dropdown 6-12
|
||||
// Spreading Factor — dropdown 5-12
|
||||
html += F("<label>Spreading Factor</label><select name='sf'>");
|
||||
for (int sf = 6; sf <= 12; sf++) {
|
||||
for (int sf = 5; sf <= 12; sf++) {
|
||||
html += F("<option value='");
|
||||
html += String(sf);
|
||||
html += "'";
|
||||
@@ -299,11 +312,16 @@ static void config_send_html() {
|
||||
);
|
||||
|
||||
// Read current blanking timeout from EEPROM (stored as minutes, 0 = never)
|
||||
uint8_t cur_blank = 0;
|
||||
uint8_t cur_blank = 5;
|
||||
if (EEPROM.read(eeprom_addr(ADDR_CONF_BSET)) == CONF_OK_BYTE) {
|
||||
cur_blank = EEPROM.read(eeprom_addr(ADDR_CONF_DBLK));
|
||||
}
|
||||
|
||||
uint8_t cur_rotation = EEPROM.read(eeprom_addr(ADDR_CONF_DROT));
|
||||
if (cur_rotation > 3) {
|
||||
cur_rotation = config_default_display_rotation();
|
||||
}
|
||||
|
||||
static const uint8_t blank_vals[] = { 0, 1, 5, 10, 30, 60 };
|
||||
static const char* blank_labels[] = { "Never", "1 minute", "5 minutes", "10 minutes", "30 minutes", "60 minutes" };
|
||||
static const int blank_count = 6;
|
||||
@@ -320,6 +338,23 @@ static void config_send_html() {
|
||||
html += F("</select>");
|
||||
html += F("<p class='note'>Turn off display after inactivity to save power</p>");
|
||||
|
||||
html += F("<label>Display Orientation</label><select name='disp_rot'>");
|
||||
html += F("<option value='0'");
|
||||
if (cur_rotation == 0) html += F(" selected");
|
||||
html += F(">Landscape</option>");
|
||||
html += F("<option value='1'");
|
||||
if (cur_rotation == 1) html += F(" selected");
|
||||
html += F(">Portrait</option>");
|
||||
html += F("<option value='2'");
|
||||
if (cur_rotation == 2) html += F(" selected");
|
||||
html += F(">Landscape Flipped</option>");
|
||||
html += F("<option value='3'");
|
||||
if (cur_rotation == 3) html += F(" selected");
|
||||
html += F(">Portrait Flipped</option>");
|
||||
html += F("</select>");
|
||||
html += F("<p class='note'>Choose the orientation that matches your OLED mounting. "
|
||||
"Landscape modes place the two status panes side by side; portrait modes stack them.</p>");
|
||||
|
||||
// ── Submit ──
|
||||
html += F(
|
||||
"<button type='submit'>Save & Reboot</button>"
|
||||
@@ -353,6 +388,14 @@ static void config_handle_save() {
|
||||
// Set WiFi mode to STA
|
||||
EEPROM.write(eeprom_addr(ADDR_CONF_WIFI), WR_WIFI_STA);
|
||||
|
||||
// Boundary mode always uses DHCP on the STA interface. Clear the legacy
|
||||
// static IP and netmask slots so stale values from older firmware or tools
|
||||
// cannot force a persistent static address.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
EEPROM.write(config_addr(ADDR_CONF_IP + i), 0x00);
|
||||
EEPROM.write(config_addr(ADDR_CONF_NM + i), 0x00);
|
||||
}
|
||||
|
||||
// ── WiFi enable setting ──
|
||||
boundary_state.wifi_enabled = (config_server->arg("wifi_en").toInt() == 1);
|
||||
|
||||
@@ -370,6 +413,12 @@ static void config_handle_save() {
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_DBLK), blank_val);
|
||||
}
|
||||
|
||||
int display_rotation = config_server->arg("disp_rot").toInt();
|
||||
if (display_rotation < 0 || display_rotation > 3) {
|
||||
display_rotation = config_default_display_rotation();
|
||||
}
|
||||
eeprom_update(eeprom_addr(ADDR_CONF_DROT), (uint8_t)display_rotation);
|
||||
|
||||
// ── TCP backbone settings ──
|
||||
boundary_state.tcp_mode = (uint8_t)config_server->arg("tcp_mode").toInt(); // 0=disabled, 1=client
|
||||
if (boundary_state.tcp_mode > 1) boundary_state.tcp_mode = 0;
|
||||
@@ -421,7 +470,7 @@ static void config_handle_save() {
|
||||
if (bw_val > 0) lora_bw = bw_val;
|
||||
|
||||
int sf_val = config_server->arg("sf").toInt();
|
||||
if (sf_val >= 6 && sf_val <= 12) lora_sf = sf_val;
|
||||
if (sf_val >= 5 && sf_val <= 12) lora_sf = sf_val;
|
||||
|
||||
int cr_val = config_server->arg("cr").toInt();
|
||||
if (cr_val >= 5 && cr_val <= 8) lora_cr = cr_val;
|
||||
@@ -481,6 +530,14 @@ static void config_handle_redirect() {
|
||||
|
||||
// ─── Check if config is needed ───────────────────────────────────────────────
|
||||
bool boundary_needs_config() {
|
||||
// If the RTNode app marker is missing, this node was either never
|
||||
// configured by RTNode or was flashed from a different firmware family
|
||||
// such as stock RNode. Force the portal so RTNode can claim and rewrite
|
||||
// its persisted settings explicitly.
|
||||
if (!boundary_app_marker_valid()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if WiFi SSID is configured
|
||||
char ssid[33];
|
||||
for (int i = 0; i < 32; i++) {
|
||||
@@ -557,6 +614,10 @@ void config_portal_start() {
|
||||
display.display();
|
||||
}
|
||||
#endif
|
||||
// Headless: LED ramp will be driven from the WCC portal loop
|
||||
if (headless_mode) {
|
||||
Serial.println("[Config] Headless mode — LED will breathe during config portal");
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Stop Config Portal ──────────────────────────────────────────────────────
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
// Copyright (C) 2026, Boundary Mode Extension
|
||||
// Based on microReticulum_Firmware by Mark Qvist
|
||||
//
|
||||
// BoundaryMode.h — Configuration and runtime state for the Boundary Mode
|
||||
// firmware variant. This header defines the WiFi backbone connection
|
||||
// parameters and boundary-specific operational settings.
|
||||
// BoundaryMode.h — Configuration and runtime state for the legacy
|
||||
// "Boundary Mode" firmware variant. Going forward this should be renamed
|
||||
// "Transport Mode". It is the only intended operating mode for this fork;
|
||||
// the old multi-mode split is kept only for compatibility while the codebase
|
||||
// is being simplified.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -15,8 +17,19 @@
|
||||
|
||||
#ifdef BOUNDARY_MODE
|
||||
|
||||
// Compatibility alias for the planned rename from Boundary Mode to
|
||||
// Transport Mode. New code should prefer the transport terminology even
|
||||
// while the legacy BOUNDARY_MODE compile-time flag still exists.
|
||||
#ifndef TRANSPORT_MODE
|
||||
#define TRANSPORT_MODE 1
|
||||
#endif
|
||||
|
||||
// ─── Boundary Mode Configuration ────────────────────────────────────────────
|
||||
//
|
||||
// NOTE: "Boundary Mode" is the legacy name. This should be relabeled
|
||||
// "Transport Mode" once the remaining non-transport code paths are removed.
|
||||
// In practice this is the only supported mode in this firmware branch.
|
||||
//
|
||||
// The boundary node operates with TWO RNS interfaces:
|
||||
//
|
||||
// 1. LoRaInterface (MODE_GATEWAY) — radio side, handles LoRa mesh
|
||||
@@ -72,10 +85,16 @@
|
||||
#define ADDR_CONF_IFAC_EN 0xD6 // IFAC enable flag (1 byte, 0x73 = enabled)
|
||||
#define ADDR_CONF_IFAC_NAME 0xD7 // Network name (33 bytes, null-terminated)
|
||||
#define ADDR_CONF_IFAC_PASS 0xF8 // Passphrase (33 bytes, null-terminated)
|
||||
// Total: 0x119 (281 bytes — extends beyond 256-byte CONFIG area into
|
||||
#define ADDR_CONF_APP_MARKER0 0x119 // RTNode app marker byte 0
|
||||
#define ADDR_CONF_APP_MARKER1 0x11A // RTNode app marker byte 1
|
||||
#define ADDR_CONF_APP_VERSION 0x11B // RTNode app config version
|
||||
// Total: 0x11C (284 bytes — extends beyond 256-byte CONFIG area into
|
||||
// unused EEPROM gap; safe on ESP32 where EEPROM starts at 824)
|
||||
|
||||
#define BOUNDARY_ENABLE_BYTE 0x73
|
||||
#define BOUNDARY_APP_MARKER0 0x52
|
||||
#define BOUNDARY_APP_MARKER1 0x54
|
||||
#define BOUNDARY_APP_VERSION 0x01
|
||||
|
||||
// ─── Boundary Mode Runtime State ─────────────────────────────────────────────
|
||||
#ifndef BOUNDARY_STATE_DEFINED
|
||||
@@ -115,6 +134,24 @@ extern BoundaryState boundary_state;
|
||||
|
||||
// ─── Boundary Mode EEPROM Load/Save ─────────────────────────────────────────
|
||||
|
||||
inline bool boundary_app_marker_valid() {
|
||||
return EEPROM.read(config_addr(ADDR_CONF_APP_MARKER0)) == BOUNDARY_APP_MARKER0 &&
|
||||
EEPROM.read(config_addr(ADDR_CONF_APP_MARKER1)) == BOUNDARY_APP_MARKER1;
|
||||
}
|
||||
|
||||
inline bool boundary_app_version_matches() {
|
||||
return boundary_app_marker_valid() &&
|
||||
EEPROM.read(config_addr(ADDR_CONF_APP_VERSION)) == BOUNDARY_APP_VERSION;
|
||||
}
|
||||
|
||||
inline void boundary_clear_app_marker() {
|
||||
EEPROM.write(config_addr(ADDR_CONF_APP_MARKER0), 0xFF);
|
||||
EEPROM.write(config_addr(ADDR_CONF_APP_MARKER1), 0xFF);
|
||||
EEPROM.write(config_addr(ADDR_CONF_APP_VERSION), 0xFF);
|
||||
EEPROM.write(config_addr(ADDR_CONF_BMODE), 0xFF);
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
inline void boundary_load_config() {
|
||||
// Check if boundary mode is configured
|
||||
uint8_t bmode = EEPROM.read(config_addr(ADDR_CONF_BMODE));
|
||||
@@ -258,6 +295,9 @@ inline void boundary_save_config() {
|
||||
EEPROM.write(config_addr(ADDR_CONF_IFAC_PASS + i), boundary_state.ifac_passphrase[i]);
|
||||
}
|
||||
EEPROM.write(config_addr(ADDR_CONF_IFAC_PASS + 32), 0x00);
|
||||
EEPROM.write(config_addr(ADDR_CONF_APP_MARKER0), BOUNDARY_APP_MARKER0);
|
||||
EEPROM.write(config_addr(ADDR_CONF_APP_MARKER1), BOUNDARY_APP_MARKER1);
|
||||
EEPROM.write(config_addr(ADDR_CONF_APP_VERSION), BOUNDARY_APP_VERSION);
|
||||
|
||||
EEPROM.commit();
|
||||
}
|
||||
|
||||
10
Config.h
10
Config.h
@@ -114,7 +114,14 @@
|
||||
#define CSMA_CW_PER_BAND_WINDOWS 15
|
||||
#define CSMA_BAND_1_MAX_AIRTIME 7
|
||||
#define CSMA_BAND_N_MIN_AIRTIME 85
|
||||
#define CSMA_INFR_THRESHOLD_DB 11
|
||||
|
||||
// Increase threshold for specific boards
|
||||
#if BOARD_MODEL == BOARD_MESHADVENTURER_S3
|
||||
#define CSMA_INFR_THRESHOLD_DB 14
|
||||
#else
|
||||
#define CSMA_INFR_THRESHOLD_DB 11
|
||||
#endif
|
||||
|
||||
#define CSMA_RFENV_RECAL_MS 2500
|
||||
#define CSMA_RFENV_RECAL_LIMIT_DB -83
|
||||
bool interference_detected = false;
|
||||
@@ -145,6 +152,7 @@
|
||||
bool hw_ready = false;
|
||||
bool radio_error = false;
|
||||
bool disp_ready = false;
|
||||
bool headless_mode = false;
|
||||
bool pmu_ready = false;
|
||||
bool promisc = false;
|
||||
bool implicit = false;
|
||||
|
||||
10
Display.h
10
Display.h
@@ -97,6 +97,11 @@ extern BoundaryState boundary_state;
|
||||
#define DISP_ADDR 0x3C
|
||||
#define SCL_OLED 18
|
||||
#define SDA_OLED 17
|
||||
#elif BOARD_MODEL == BOARD_MESHADVENTURER_S3
|
||||
#define DISP_RST -1
|
||||
#define DISP_ADDR 0x3C
|
||||
#define SCL_OLED 44
|
||||
#define SDA_OLED 42
|
||||
#elif BOARD_MODEL == BOARD_RAK4631
|
||||
// RAK1921/SSD1306
|
||||
#define DISP_RST -1
|
||||
@@ -334,6 +339,8 @@ bool display_init() {
|
||||
digitalWrite(pin_display_en, HIGH);
|
||||
delay(50);
|
||||
Wire.begin(SDA_OLED, SCL_OLED);
|
||||
#elif BOARD_MODEL == BOARD_MESHADVENTURER_S3
|
||||
Wire.begin(SDA_OLED, SCL_OLED);
|
||||
#elif BOARD_MODEL == BOARD_LORA32_V1_0
|
||||
int pin_display_en = 16;
|
||||
digitalWrite(pin_display_en, LOW);
|
||||
@@ -455,6 +462,9 @@ bool display_init() {
|
||||
#elif BOARD_MODEL == BOARD_HELTEC32_V4
|
||||
disp_mode = DISP_MODE_PORTRAIT;
|
||||
display.setRotation(1);
|
||||
#elif BOARD_MODEL == BOARD_MESHADVENTURER_S3
|
||||
disp_mode = DISP_MODE_LANDSCAPE;
|
||||
display.setRotation(0);
|
||||
#elif BOARD_MODEL == BOARD_HELTEC_T114
|
||||
disp_mode = DISP_MODE_PORTRAIT;
|
||||
display.setRotation(1);
|
||||
|
||||
3
Input.h
3
Input.h
@@ -96,6 +96,9 @@
|
||||
display.display();
|
||||
}
|
||||
#endif
|
||||
headless_led_fast_blink();
|
||||
} else if (display_lock_white) {
|
||||
headless_led_fast_blink();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
Power.h
17
Power.h
@@ -147,6 +147,23 @@ float pmu_temperature = PMU_TEMP_MIN-1;
|
||||
bool bat_voltage_dropping = false;
|
||||
float bat_delay_v = 0;
|
||||
float bat_state_change_v = 0;
|
||||
#elif BOARD_MODEL == BOARD_MESHADVENTURER_S3
|
||||
#define BAT_V_MIN 3.05
|
||||
#define BAT_V_MAX 4.0
|
||||
#define BAT_V_CHG 4.48
|
||||
#define BAT_V_FLOAT 4.33
|
||||
#define BAT_SAMPLES 7
|
||||
const uint8_t pin_vbat = 1;
|
||||
const uint8_t pin_ctrl = 37;
|
||||
float bat_p_samples[BAT_SAMPLES];
|
||||
float bat_v_samples[BAT_SAMPLES];
|
||||
uint8_t bat_samples_count = 0;
|
||||
int bat_discharging_samples = 0;
|
||||
int bat_charging_samples = 0;
|
||||
int bat_charged_samples = 0;
|
||||
bool bat_voltage_dropping = false;
|
||||
float bat_delay_v = 0;
|
||||
float bat_state_change_v = 0;
|
||||
#elif BOARD_MODEL == BOARD_HELTEC_T114
|
||||
#define BAT_V_MIN 3.15
|
||||
#define BAT_V_MAX 4.165
|
||||
|
||||
16
README.md
16
README.md
@@ -2,6 +2,8 @@
|
||||
|
||||
A custom firmware for the **Heltec WiFi LoRa 32 V4** (ESP32-S3 + SX1262) that operates as a **Transport Node** — bridging a local LoRa radio network with a remote TCP/IP backbone (such as [rmap.world](https://rmap.world)) over WiFi.
|
||||
|
||||
This project was primarily developed with the use of AI assistance.
|
||||
|
||||
```
|
||||
Android / Sideband Remote
|
||||
┌──────────┐ ┌────────────┐ Reticulum
|
||||
@@ -52,25 +54,27 @@ This firmware was designed for the **Heltec WiFi LoRa 32 V4**. This board was ch
|
||||
The easiest way to flash a pre-built firmware. You only need Python 3 and a USB cable.
|
||||
|
||||
```bash
|
||||
# Install esptool (one time)
|
||||
pip install esptool
|
||||
|
||||
# Clone this repo (or download just flash.py + the firmware binary)
|
||||
git clone https://github.com/jrl290/RTNode-HeltecV4.git
|
||||
cd RTNode-HeltecV4
|
||||
|
||||
# Download latest firmware from GitHub Releases and flash
|
||||
# (auto-detects V3 vs V4 from flash size)
|
||||
python flash.py --download
|
||||
python flash.py
|
||||
|
||||
# Optional: use your machine's installed esptool instead of the bundled copy
|
||||
python flash.py --use-system-esptool
|
||||
|
||||
# Or specify board explicitly
|
||||
python flash.py --download --board v3
|
||||
python flash.py --download --board v4
|
||||
python flash.py --board v3
|
||||
python flash.py --board v4
|
||||
|
||||
# Or flash a local binary
|
||||
python flash.py --file rtnode_heltec_v4.bin
|
||||
```
|
||||
|
||||
By default, `flash.py` uses the bundled `Release/esptool/esptool.py` for reproducible flashing. Only use `--use-system-esptool` if you explicitly want to override that with a host-installed esptool.
|
||||
|
||||
The flash utility auto-detects whether a V3 or V4 is connected by querying the flash size (8MB = V3, 16MB = V4). You can override with `--board v3` or `--board v4`. It will list all available serial ports and prompt you to choose one. If no ports are detected, you may need to hold the **BOOT** button while pressing **RESET** to enter download mode.
|
||||
|
||||
### Option B: Build from Source (PlatformIO)
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#include "Utilities.h"
|
||||
|
||||
// CBA Boundary Mode
|
||||
// NOTE: Boundary Mode is the legacy name. This firmware branch intends to
|
||||
// converge on a single Transport Mode, with the BOUNDARY_MODE symbol kept
|
||||
// temporarily as a compatibility shim during cleanup.
|
||||
#ifdef BOUNDARY_MODE
|
||||
#include "BoundaryMode.h"
|
||||
#include "TcpInterface.h"
|
||||
@@ -243,6 +246,9 @@ TcpInterface* local_tcp_interface_ptr = nullptr;
|
||||
// RTC memory flag — survives software reset but not power cycle
|
||||
RTC_NOINIT_ATTR uint32_t boundary_config_request;
|
||||
#define BOUNDARY_CONFIG_MAGIC 0xC0F19A7E
|
||||
// RTC flag to skip config portal on next boot (set when user powers off from WCC)
|
||||
RTC_NOINIT_ATTR uint32_t boundary_skip_config;
|
||||
#define BOUNDARY_SKIP_MAGIC 0x5E1FC0F0
|
||||
|
||||
// Bootloop detection: count rapid reboots in RTC memory.
|
||||
// After BOOTLOOP_THRESHOLD consecutive reboots within BOOTLOOP_WINDOW_MS,
|
||||
@@ -350,7 +356,7 @@ void setup() {
|
||||
boot_seq();
|
||||
#endif
|
||||
|
||||
#if BOARD_MODEL != BOARD_RAK4631 && BOARD_MODEL != BOARD_HELTEC_T114 && BOARD_MODEL != BOARD_TECHO && BOARD_MODEL != BOARD_T3S3 && BOARD_MODEL != BOARD_TBEAM_S_V1 && BOARD_MODEL != BOARD_HELTEC32_V4 && BOARD_MODEL != BOARD_HELTEC32_V3
|
||||
#if BOARD_MODEL != BOARD_RAK4631 && BOARD_MODEL != BOARD_HELTEC_T114 && BOARD_MODEL != BOARD_TECHO && BOARD_MODEL != BOARD_T3S3 && BOARD_MODEL != BOARD_TBEAM_S_V1 && BOARD_MODEL != BOARD_HELTEC32_V4 && BOARD_MODEL != BOARD_HELTEC32_V3 && BOARD_MODEL != BOARD_MESHADVENTURER_S3
|
||||
// Some boards need to wait until the hardware UART is set up before booting
|
||||
// the full firmware. In the case of the RAK4631, Heltec T114, and Heltec V3,
|
||||
// the line below will wait until a serial connection is actually established
|
||||
@@ -473,7 +479,17 @@ void setup() {
|
||||
|
||||
display_unblank();
|
||||
disp_ready = display_init();
|
||||
update_display();
|
||||
if (disp_ready) {
|
||||
update_display();
|
||||
} else {
|
||||
headless_mode = true;
|
||||
Serial.println("[Headless] No display detected — running in headless mode");
|
||||
}
|
||||
#endif
|
||||
|
||||
// LED solid on at boot for V3/V4 boards (with or without display)
|
||||
#if BOARD_MODEL == BOARD_HELTEC32_V4 || BOARD_MODEL == BOARD_HELTEC32_V3
|
||||
headless_led_solid();
|
||||
#endif
|
||||
|
||||
// ── Boundary Mode: check if config portal is needed ──
|
||||
@@ -512,22 +528,66 @@ void setup() {
|
||||
|
||||
// Enter config mode if: first boot with no config, OR button-triggered reboot,
|
||||
// OR bootloop detected
|
||||
bool app_marker_missing = !boundary_app_marker_valid();
|
||||
bool need_config = boundary_needs_config();
|
||||
bool config_requested = (boundary_config_request == BOUNDARY_CONFIG_MAGIC);
|
||||
bool skip_config = (boundary_skip_config == BOUNDARY_SKIP_MAGIC);
|
||||
boundary_config_request = 0; // Clear flag immediately
|
||||
boundary_skip_config = 0; // Clear skip flag immediately
|
||||
|
||||
// Skip flag only suppresses a button-triggered re-entry, not a genuinely
|
||||
// unconfigured device. If there's no config saved, always show the portal.
|
||||
if (skip_config && config_requested) {
|
||||
Serial.println("[Boundary] Skipping config portal — user requested normal boot");
|
||||
config_requested = false;
|
||||
}
|
||||
|
||||
if (need_config || config_requested || bootloop_detected) {
|
||||
if (bootloop_detected) {
|
||||
Serial.println("[Boundary] Entering config portal due to bootloop recovery");
|
||||
} else if (config_requested) {
|
||||
Serial.println("[Boundary] Config mode requested via button hold");
|
||||
} else if (app_marker_missing) {
|
||||
Serial.println("[Boundary] RTNode app marker missing — previous firmware was not RTNode or config is unclaimed");
|
||||
Serial.println("[Boundary] Starting config portal to migrate settings into RTNode");
|
||||
} else {
|
||||
Serial.println("[Boundary] No configuration found — starting config portal");
|
||||
}
|
||||
config_portal_start();
|
||||
// Block here: only run the config portal until user saves and device reboots
|
||||
// Track button state for "off" action (1-3s press = sleep)
|
||||
bool wcc_btn_down = false;
|
||||
uint32_t wcc_btn_down_at = 0;
|
||||
while (config_portal_is_active()) {
|
||||
config_portal_loop();
|
||||
|
||||
// Headless LED: slow ramp breathe effect during WCC mode
|
||||
headless_led_ramp();
|
||||
|
||||
// Button handling: allow 1-3s press to turn off (deep sleep)
|
||||
// Next power-on boots to normal mode since boundary_config_request is cleared
|
||||
#if HAS_INPUT
|
||||
{
|
||||
int btn = digitalRead(pin_btn_usr1);
|
||||
if (btn == LOW && !wcc_btn_down) {
|
||||
wcc_btn_down = true;
|
||||
wcc_btn_down_at = millis();
|
||||
} else if (btn == HIGH && wcc_btn_down) {
|
||||
uint32_t held = millis() - wcc_btn_down_at;
|
||||
wcc_btn_down = false;
|
||||
if (held >= 700 && held <= 5000) {
|
||||
Serial.println("[Boundary] Button press in WCC mode — powering off");
|
||||
boundary_skip_config = BOUNDARY_SKIP_MAGIC; // Skip config on next boot
|
||||
headless_led_off();
|
||||
config_portal_stop();
|
||||
#if HAS_SLEEP
|
||||
sleep_now();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MCU_VARIANT == MCU_ESP32
|
||||
esp_task_wdt_reset();
|
||||
#endif
|
||||
@@ -1681,6 +1741,9 @@ void serial_callback(uint8_t sbyte) {
|
||||
eeprom_conf_save();
|
||||
} else if (command == CMD_CONF_DELETE) {
|
||||
eeprom_conf_delete();
|
||||
#ifdef BOUNDARY_MODE
|
||||
boundary_clear_app_marker();
|
||||
#endif
|
||||
} else if (command == CMD_FB_EXT) {
|
||||
#if HAS_DISPLAY == true
|
||||
if (sbyte == 0xFF) {
|
||||
@@ -2511,6 +2574,13 @@ void loop() {
|
||||
if (disp_ready && !display_updating) update_display();
|
||||
#endif
|
||||
|
||||
// LED solid when operational on V3/V4 boards (yield to fast blink during white screen)
|
||||
#if BOARD_MODEL == BOARD_HELTEC32_V4 || BOARD_MODEL == BOARD_HELTEC32_V3
|
||||
if (radio_online && !display_lock_white) {
|
||||
headless_led_solid();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_PMU
|
||||
if (pmu_ready) update_pmu();
|
||||
#endif
|
||||
@@ -2558,6 +2628,8 @@ void sleep_now() {
|
||||
#endif
|
||||
#endif
|
||||
#if BOARD_MODEL == BOARD_HELTEC32_V4
|
||||
headless_led_off();
|
||||
headless_led_detach_pwm();
|
||||
digitalWrite(LORA_PA_CPS, LOW);
|
||||
digitalWrite(LORA_PA_CSD, LOW);
|
||||
digitalWrite(LORA_PA_PWR_EN, LOW);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Release/rnode_firmware_heltec32v3.bin
Executable file
BIN
Release/rnode_firmware_heltec32v3.bin
Executable file
Binary file not shown.
Binary file not shown.
8
Remote.h
8
Remote.h
@@ -78,6 +78,13 @@ void wifi_remote_start_ap() {
|
||||
void wifi_remote_start_sta() {
|
||||
WiFi.mode(WIFI_STA);
|
||||
|
||||
#ifdef BOUNDARY_MODE
|
||||
// Boundary mode does not expose static STA addressing in its config flow.
|
||||
// Always return the station interface to DHCP so stale legacy EEPROM data
|
||||
// cannot pin the node to an unintended address.
|
||||
WiFi.config(INADDR_NONE, INADDR_NONE, INADDR_NONE);
|
||||
#else
|
||||
|
||||
uint8_t ip[4]; bool ip_ok = true;
|
||||
for (uint8_t i = 0; i < 4; i++) { ip[i] = EEPROM.read(config_addr(ADDR_CONF_IP+i)); }
|
||||
if (ip[0]==0x00 && ip[1]==0x00 && ip[2]==0x00 && ip[3]==0x00) { ip_ok = false; }
|
||||
@@ -97,6 +104,7 @@ void wifi_remote_start_sta() {
|
||||
IPAddress dns2(1, 1, 1, 1);
|
||||
WiFi.config(sta_ip, sta_gw, sta_nm, dns1, dns2);
|
||||
}
|
||||
#endif
|
||||
|
||||
delay(100);
|
||||
if (wr_ssid[0] != 0x00) {
|
||||
|
||||
94
Utilities.h
94
Utilities.h
@@ -72,6 +72,10 @@ uint8_t eeprom_read(uint32_t mapped_addr);
|
||||
#endif
|
||||
|
||||
#if HAS_INPUT == true
|
||||
// Forward declarations for headless LED functions (defined later in this file)
|
||||
void headless_led_fast_blink();
|
||||
void headless_led_ramp();
|
||||
void headless_led_off();
|
||||
#include "Input.h"
|
||||
#endif
|
||||
|
||||
@@ -320,6 +324,13 @@ extern RNS::Reticulum reticulum;
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_MESHADVENTURER_S3
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
void led_tx_on() { digitalWrite(pin_led_tx, HIGH); }
|
||||
void led_tx_off() { digitalWrite(pin_led_tx, LOW); }
|
||||
void led_id_on() { }
|
||||
void led_id_off() { }
|
||||
#elif BOARD_MODEL == BOARD_LORA32_V2_1
|
||||
void led_rx_on() { digitalWrite(pin_led_rx, HIGH); }
|
||||
void led_rx_off() { digitalWrite(pin_led_rx, LOW); }
|
||||
@@ -382,6 +393,79 @@ extern RNS::Reticulum reticulum;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ── Headless LED indicators (for Heltec V4 without OLED) ─────────────────
|
||||
// Uses LEDC PWM for smooth ramp effects on pin_led_tx (GPIO 35)
|
||||
#if BOARD_MODEL == BOARD_HELTEC32_V4 || BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == MESHADVENTURER_S3
|
||||
#define HEADLESS_LED_CHANNEL 0
|
||||
bool headless_led_pwm_attached = false;
|
||||
|
||||
void headless_led_ensure_pwm() {
|
||||
if (!headless_led_pwm_attached) {
|
||||
ledcSetup(HEADLESS_LED_CHANNEL, 5000, 8); // channel 0, 5kHz, 8-bit
|
||||
ledcAttachPin(pin_led_tx, HEADLESS_LED_CHANNEL);
|
||||
headless_led_pwm_attached = true;
|
||||
}
|
||||
}
|
||||
|
||||
void headless_led_detach_pwm() {
|
||||
if (headless_led_pwm_attached) {
|
||||
ledcDetachPin(pin_led_tx);
|
||||
headless_led_pwm_attached = false;
|
||||
pinMode(pin_led_tx, OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
// Solid ON — normal headless operation
|
||||
void headless_led_solid() {
|
||||
headless_led_ensure_pwm();
|
||||
ledcWrite(HEADLESS_LED_CHANNEL, 255);
|
||||
}
|
||||
|
||||
// Fast blink — replaces "white screen" indicator (non-blocking, call from loop)
|
||||
void headless_led_fast_blink() {
|
||||
headless_led_ensure_pwm();
|
||||
static uint32_t last_toggle = 0;
|
||||
static bool on = false;
|
||||
uint32_t now = millis();
|
||||
if (now - last_toggle >= 100) { // 5Hz blink
|
||||
last_toggle = now;
|
||||
on = !on;
|
||||
ledcWrite(HEADLESS_LED_CHANNEL, on ? 255 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Slow ramp in/out — breathe effect for WiFi Captive Configure mode
|
||||
void headless_led_ramp() {
|
||||
headless_led_ensure_pwm();
|
||||
static uint32_t last_step = 0;
|
||||
static uint8_t brightness = 0;
|
||||
static int8_t direction = 1;
|
||||
uint32_t now = millis();
|
||||
if (now - last_step >= 10) { // ~100 steps/sec, full cycle ~5 seconds
|
||||
last_step = now;
|
||||
brightness += direction;
|
||||
if (brightness >= 255) { brightness = 255; direction = -1; }
|
||||
if (brightness == 0) { direction = 1; }
|
||||
ledcWrite(HEADLESS_LED_CHANNEL, brightness);
|
||||
}
|
||||
}
|
||||
|
||||
void headless_led_off() {
|
||||
if (headless_led_pwm_attached) {
|
||||
ledcWrite(HEADLESS_LED_CHANNEL, 0);
|
||||
} else {
|
||||
digitalWrite(pin_led_tx, LOW);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void headless_led_ensure_pwm() {}
|
||||
void headless_led_detach_pwm() {}
|
||||
void headless_led_solid() {}
|
||||
void headless_led_fast_blink() {}
|
||||
void headless_led_ramp() {}
|
||||
void headless_led_off() {}
|
||||
#endif
|
||||
|
||||
void hard_reset(void) {
|
||||
#if MCU_VARIANT == MCU_1284P || MCU_VARIANT == MCU_2560
|
||||
wdt_enable(WDTO_15MS);
|
||||
@@ -1696,10 +1780,12 @@ bool eeprom_model_valid() {
|
||||
if (model == MODEL_C5 || model == MODEL_CA) {
|
||||
#elif BOARD_MODEL == BOARD_HELTEC32_V4
|
||||
if (model == MODEL_C8) {
|
||||
#elif BOARD_MODEL == BOARD_HELTEC_T114
|
||||
if (model == MODEL_C6 || model == MODEL_C7) {
|
||||
#elif BOARD_MODEL == BOARD_RAK4631
|
||||
if (model == MODEL_11 || model == MODEL_12) {
|
||||
#elif BOARD_MODEL == BOARD_MESHADVENTURER_S3
|
||||
if (model == MODEL_C8) {
|
||||
#elif BOARD_MODEL == BOARD_HELTEC_T114
|
||||
if (model == MODEL_C6 || model == MODEL_C7) {
|
||||
#elif BOARD_MODEL == BOARD_RAK4631
|
||||
if (model == MODEL_11 || model == MODEL_12) {
|
||||
#elif BOARD_MODEL == BOARD_HUZZAH32
|
||||
if (model == MODEL_FF) {
|
||||
#elif BOARD_MODEL == BOARD_GENERIC_ESP32
|
||||
|
||||
@@ -121,6 +121,8 @@ def device_provision(env):
|
||||
env.Execute("rnodeconf --product b1 --model b9 --hwrev 1 --rom " + env.subst("$UPLOAD_PORT"))
|
||||
elif variant in ("heltec32v4", "heltec32v4_local", "heltec32v4_boundary", "heltec32v4_boundary_local"):
|
||||
env.Execute("rnodeconf --product b1 --model b9 --hwrev 1 --rom " + env.subst("$UPLOAD_PORT"))
|
||||
elif variant in ("meshadventurer_s3_boundary"):
|
||||
env.Execute("rnodeconf --product f0 --model fe --hwrev 1 --rom " + env.subst("$UPLOAD_PORT"))
|
||||
elif variant in ("rak4631", "rak4631_local"):
|
||||
env.Execute("rnodeconf --product 10 --model 12 --hwrev 1 --rom " + env.subst("$UPLOAD_PORT"))
|
||||
elif variant in ("heltec_t114", "heltec_t114_local"):
|
||||
|
||||
16
flash.py
16
flash.py
@@ -323,8 +323,6 @@ def find_esptool():
|
||||
usually the newest version), then fall back to the bundled script.
|
||||
"""
|
||||
# 1. pip-installed esptool on PATH
|
||||
if shutil.which("esptool.py"):
|
||||
return ["esptool.py"]
|
||||
if shutil.which("esptool"):
|
||||
return ["esptool"]
|
||||
|
||||
@@ -851,8 +849,8 @@ def flash_firmware(firmware_path, port, esptool_cmd, baud=None,
|
||||
flash_addr = f"0x{APP_ADDR:x}"
|
||||
print(f" Detected: app-only binary -> flash at {flash_addr}")
|
||||
|
||||
before_arg = "no_reset" if no_reset_before else "default_reset"
|
||||
after_arg = "no_reset" if no_hard_reset else "hard_reset"
|
||||
before_arg = "no_reset" if no_reset_before else "default-reset"
|
||||
after_arg = "no_reset" if no_hard_reset else "hard-reset"
|
||||
|
||||
cmd = esptool_cmd + [
|
||||
"--chip", CHIP,
|
||||
@@ -860,14 +858,14 @@ def flash_firmware(firmware_path, port, esptool_cmd, baud=None,
|
||||
"--baud", baud,
|
||||
"--before", before_arg,
|
||||
"--after", after_arg,
|
||||
"write_flash",
|
||||
"write-flash",
|
||||
"-z",
|
||||
"--flash_mode", mode,
|
||||
"--flash_freq", FLASH_FREQ,
|
||||
"--flash_size", flash_size,
|
||||
"--flash-mode", mode,
|
||||
"--flash-freq", FLASH_FREQ,
|
||||
"--flash-size", flash_size,
|
||||
]
|
||||
if verify:
|
||||
cmd.append("--verify")
|
||||
cmd.append("--no-diff-verify")
|
||||
cmd += [flash_addr, firmware_path]
|
||||
|
||||
print("Running: " + " ".join(cmd[-8:]))
|
||||
|
||||
176
platformio.ini
176
platformio.ini
@@ -9,7 +9,6 @@
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
; Change source and include directories to root of project since RNode places them here
|
||||
include_dir = .
|
||||
src_dir = .
|
||||
|
||||
@@ -19,32 +18,18 @@ monitor_speed = 115200
|
||||
upload_speed = 460800
|
||||
build_flags =
|
||||
-Wall
|
||||
;-Wextra
|
||||
-Wno-missing-field-initializers
|
||||
-Wno-format
|
||||
-I.
|
||||
; CBA Define following to disable DEBUG build
|
||||
;-DNDEBUG
|
||||
; CBA Define following to include RNS stack
|
||||
-DHAS_RNS
|
||||
-DRNS_USE_FS
|
||||
-DRNS_PERSIST_PATHS
|
||||
-DMSGPACK_USE_BOOST=OFF
|
||||
; CBA Define following to disable LFS asserts
|
||||
;-DLFS_NO_ASSERT
|
||||
; ???
|
||||
;-DLFS_YES_TRACE
|
||||
; ???
|
||||
;-DCORE_DEBUG_LEVEL=5
|
||||
; ??? NO
|
||||
;-DLOG_LOCAL_LEVEL=5
|
||||
;-DCONFIG_LOG_DEFAULT_LEVEL=5
|
||||
lib_deps =
|
||||
ArduinoJson@^7.4.2
|
||||
MsgPack@^0.4.2
|
||||
adafruit/Adafruit SSD1306@^2.5.9
|
||||
https://github.com/attermann/Crypto.git
|
||||
; Exclude directories in root from sources
|
||||
build_src_filter = +<*> -<variants/>
|
||||
extra_scripts = pre:extra_script.py
|
||||
|
||||
@@ -57,10 +42,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_RNODE_NG_20
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.12.0
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:rnode-ng-21]
|
||||
platform = espressif32
|
||||
@@ -71,10 +56,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_RNODE_NG_21
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.12.0
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:ttgo-t-beam]
|
||||
platform = espressif32
|
||||
@@ -85,9 +70,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_TBEAM
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:ttgo-t-beam-sx1262]
|
||||
platform = espressif32
|
||||
@@ -99,9 +85,10 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_TBEAM
|
||||
-DMODEM=SX1262
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:ttgo-t-beam-supreme]
|
||||
platform = espressif32
|
||||
@@ -113,11 +100,12 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_TBEAM_S_V1
|
||||
-DMODEM=SX1262
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
Adafruit_SH110X
|
||||
adafruit/Adafruit SH110X@^2.1.14
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:lilygo-t3-s3]
|
||||
platform = espressif32
|
||||
@@ -129,9 +117,10 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_T3S3
|
||||
-DMODEM=SX1262
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:lilygo-t3-s3-sx127x]
|
||||
platform = espressif32
|
||||
@@ -143,9 +132,10 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_T3S3
|
||||
-DMODEM=SX1276
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:lilygo-t3-s3-sx1280-pa]
|
||||
platform = espressif32
|
||||
@@ -157,36 +147,33 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_T3S3
|
||||
-DMODEM=SX1280
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:lilygo-t-deck]
|
||||
platform = espressif32
|
||||
board = esp32-s3-devkitc-1
|
||||
custom_variant = tdeck
|
||||
board_build.filesystem = littlefs
|
||||
; Flash / memory layout
|
||||
board_upload.flash_size = 16MB
|
||||
board_upload.maximum_size = 16777216
|
||||
board_build.partitions = default_16MB.csv
|
||||
; Enable PSRAM + correct flash mode
|
||||
board_build.flash_mode = qio
|
||||
board_build.psram_type = opi
|
||||
board_build.arduino.memory_type = qio_opi
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_TDECK
|
||||
-DBOARD_HAS_PSRAM=1
|
||||
-DBOARD_HAS_PSRAM=1
|
||||
-DARDUINO_USB_MODE=1
|
||||
-DCORE_DEBUG_LEVEL=1
|
||||
; Enable UARDUINO_ USB_ CDC_ ON_ BOOT will start printing and wait for terminal access during startup
|
||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||
; Enable UARDUINO_USB_CDC_ON_BOOT will turn off printing and will not block when using the battery
|
||||
; -UARDUINO_USB_CDC_ON_BOOT
|
||||
lib_deps =
|
||||
-DCORE_DEBUG_LEVEL=1
|
||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:ttgo-lora32-v1]
|
||||
platform = espressif32
|
||||
@@ -197,9 +184,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_LORA32_V1_0
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:ttgo-lora32-v2]
|
||||
platform = espressif32
|
||||
@@ -210,9 +198,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_LORA32_V2_0
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:ttgo-lora32-v2-extled]
|
||||
platform = espressif32
|
||||
@@ -224,9 +213,10 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_LORA32_V1_0
|
||||
-DEXTERNAL_LEDS=true
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:ttgo-lora32-v21]
|
||||
platform = espressif32
|
||||
@@ -237,9 +227,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_LORA32_V2_1
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:ttgo-lora32-v21-extled]
|
||||
platform = espressif32
|
||||
@@ -251,9 +242,10 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_LORA32_V2_1
|
||||
-DEXTERNAL_LEDS=true
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:ttgo-lora32-v21-tcxo]
|
||||
platform = espressif32
|
||||
@@ -265,9 +257,10 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_LORA32_V2_1
|
||||
-DENABLE_TCXO=true
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:heltec_wifi_lora_32_V2]
|
||||
platform = espressif32
|
||||
@@ -278,9 +271,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_LORA32_V2_1
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:heltec_wifi_lora_32_V2-extled]
|
||||
platform = espressif32
|
||||
@@ -292,9 +286,10 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_LORA32_V2_1
|
||||
-DEXTERNAL_LEDS=true
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:heltec_wifi_lora_32_V3]
|
||||
platform = espressif32
|
||||
@@ -305,19 +300,16 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_HELTEC32_V3
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:heltec_V3_boundary]
|
||||
platform = espressif32
|
||||
board = heltec_wifi_lora_32_V3
|
||||
custom_variant = heltec32v3
|
||||
board_build.filesystem = littlefs
|
||||
; Flash / memory layout for 8MB flash
|
||||
; PSRAM: V3 ESP32-S3FN8 has NO PSRAM — firmware detects this at runtime
|
||||
; and falls back to internal SRAM for TLSF pool.
|
||||
; BOARD_HAS_PSRAM tells Arduino to *attempt* psramInit(); harmless if absent.
|
||||
board_upload.flash_size = 8MB
|
||||
board_upload.maximum_size = 8388608
|
||||
board_build.partitions = default_8MB.csv
|
||||
@@ -330,17 +322,14 @@ build_flags =
|
||||
-DBOARD_MODEL=BOARD_HELTEC32_V3
|
||||
-DBOARD_HAS_PSRAM=1
|
||||
-DBOUNDARY_MODE
|
||||
;-DNDEBUG
|
||||
-DRNS_USE_TLSF=1
|
||||
-DRNS_USE_ALLOCATOR=1
|
||||
; --- Boundary mode defaults (override via EEPROM at runtime) ---
|
||||
; TCP server mode (0=server, 1=client)
|
||||
-DBOUNDARY_TCP_MODE=0
|
||||
; TCP listen/connect port
|
||||
-DBOUNDARY_TCP_PORT=4242
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
[env:heltec_wifi_lora_32_V4]
|
||||
@@ -353,16 +342,44 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_HELTEC32_V4
|
||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:meshadventurer_S3_boundary]
|
||||
platform = espressif32
|
||||
board = esp32-s3-devkitc-1
|
||||
custom_variant = meshadventurer_s3_boundary
|
||||
board_build.filesystem = littlefs
|
||||
board_upload.flash_size = 16MB
|
||||
board_upload.maximum_size = 16777216
|
||||
board_build.partitions = default_16MB.csv
|
||||
board_build.flash_mode = qio
|
||||
board_build.psram_type = qio
|
||||
board_build.arduino.memory_type = qio_qspi
|
||||
monitor_speed = 921600
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_MESHADVENTURER_S3
|
||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||
-DBOARD_HAS_PSRAM=1
|
||||
-DBOUNDARY_MODE
|
||||
-DRNS_USE_TLSF=1
|
||||
-DRNS_USE_ALLOCATOR=1
|
||||
-DBOUNDARY_TCP_MODE=0
|
||||
-DBOUNDARY_TCP_PORT=4242
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
[env:heltec_V4_boundary]
|
||||
platform = espressif32
|
||||
board = esp32-s3-devkitc-1
|
||||
custom_variant = heltec32v4_boundary
|
||||
board_build.filesystem = littlefs
|
||||
; Flash / memory layout for 16MB flash + 2MB PSRAM
|
||||
board_upload.flash_size = 16MB
|
||||
board_upload.maximum_size = 16777216
|
||||
board_build.partitions = default_16MB.csv
|
||||
@@ -376,20 +393,14 @@ build_flags =
|
||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||
-DBOARD_HAS_PSRAM=1
|
||||
-DBOUNDARY_MODE
|
||||
;-DNDEBUG
|
||||
-DRNS_USE_TLSF=1
|
||||
-DRNS_USE_ALLOCATOR=1
|
||||
; --- Boundary mode defaults (override via EEPROM at runtime) ---
|
||||
; TCP server mode (0=server, 1=client)
|
||||
-DBOUNDARY_TCP_MODE=0
|
||||
; TCP listen/connect port
|
||||
-DBOUNDARY_TCP_PORT=4242
|
||||
; Backbone host for client mode (empty = server mode)
|
||||
; -DBOUNDARY_BACKBONE_HOST=\"192.168.1.100\"
|
||||
; -DBOUNDARY_BACKBONE_PORT=4242
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
[env:heltec_V4_boundary-local]
|
||||
@@ -411,9 +422,10 @@ build_flags =
|
||||
-DBOUNDARY_MODE
|
||||
-DBOUNDARY_TCP_MODE=0
|
||||
-DBOUNDARY_TCP_PORT=4242
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
[env:featheresp32]
|
||||
@@ -425,9 +437,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_HUZZAH32
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:seeed_xiao_esp32s3]
|
||||
platform = espressif32
|
||||
@@ -438,9 +451,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_XIAO_S3
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:generic-esp32]
|
||||
platform = espressif32
|
||||
@@ -451,9 +465,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_GENERIC_ESP32
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:wiscore_rak4631]
|
||||
platform = nordicnrf52
|
||||
@@ -469,10 +484,9 @@ build_flags =
|
||||
-DBOARD_MODEL=BOARD_RAK4631
|
||||
-DRNS_USE_TLSF=1
|
||||
-DRNS_USE_ALLOCATOR=1
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
|
||||
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:ttgo-t-beam-local]
|
||||
platform = espressif32
|
||||
@@ -481,16 +495,15 @@ upload_speed = 460800
|
||||
custom_variant = tbeam_local
|
||||
board_build.partitions = no_ota.csv
|
||||
board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-fexceptions
|
||||
-DBOARD_MODEL=BOARD_TBEAM
|
||||
; CBA TEST
|
||||
;-DUSE_FLASHFS=1
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
Adafruit_SPIFlash=symlink://../Adafruit_SPIFlash
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
[env:ttgo-lora32-v21-local]
|
||||
@@ -503,9 +516,10 @@ board_build.filesystem = littlefs
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_LORA32_V2_1
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
[env:heltec_wifi_lora_32_V4-local]
|
||||
@@ -518,9 +532,10 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-DBOARD_MODEL=BOARD_HELTEC32_V4
|
||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
XPowersLib@^0.2.1
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
monitor_filters = esp32_exception_decoder
|
||||
|
||||
[env:wiscore_rak4631-local]
|
||||
@@ -535,17 +550,15 @@ build_flags =
|
||||
-I variants/rak4630
|
||||
-fexceptions
|
||||
-DBOARD_MODEL=BOARD_RAK4631
|
||||
; CBA TEST
|
||||
-DRNS_USE_TLSF=1
|
||||
-DRNS_USE_ALLOCATOR=1
|
||||
;-DUSE_FLASHFS=1
|
||||
build_unflags = -fno-exceptions
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
Adafruit_SPIFlash=symlink://../Adafruit_SPIFlash
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
[env:heltec_t114_local]
|
||||
;upload_port = /dev/cu.usbmodem1101
|
||||
platform = nordicnrf52
|
||||
board = nrf52840_dk_adafruit
|
||||
custom_variant = heltec_t114_local
|
||||
@@ -555,11 +568,10 @@ build_flags =
|
||||
${env.build_flags}
|
||||
-fexceptions
|
||||
-DBOARD_MODEL=BOARD_HELTEC_T114
|
||||
; CBA TEST
|
||||
-DRNS_USE_TLSF=1
|
||||
-DRNS_USE_ALLOCATOR=1
|
||||
build_unflags = -fno-exceptions
|
||||
lib_deps =
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
https://github.com/liamcottle/esp8266-oled-ssd1306#e16cee124fe26490cb14880c679321ad8ac89c95
|
||||
adafruit/Adafruit NeoPixel@^1.12.0
|
||||
adafruit/Adafruit NeoPixel@^1.15.4
|
||||
|
||||
@@ -126,7 +126,7 @@ bool sx126x::preInit() {
|
||||
pinMode(_ss, OUTPUT);
|
||||
digitalWrite(_ss, HIGH);
|
||||
|
||||
#if BOARD_MODEL == BOARD_T3S3 || BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == BOARD_HELTEC32_V4 || BOARD_MODEL == BOARD_TDECK || BOARD_MODEL == BOARD_XIAO_S3
|
||||
#if BOARD_MODEL == BOARD_T3S3 || BOARD_MODEL == BOARD_HELTEC32_V3 || BOARD_MODEL == BOARD_HELTEC32_V4 || BOARD_MODEL == BOARD_TDECK || BOARD_MODEL == BOARD_XIAO_S3 || BOARD_MODEL == BOARD_MESHADVENTURER_S3
|
||||
SPI.begin(pin_sclk, pin_miso, pin_mosi, pin_cs);
|
||||
#elif BOARD_MODEL == BOARD_TECHO
|
||||
SPI.setPins(pin_miso, pin_sclk, pin_mosi);
|
||||
@@ -643,6 +643,8 @@ void sx126x::enableTCXO() {
|
||||
uint8_t buf[4] = {MODE_TCXO_1_8V_6X, 0x00, 0x00, 0xFF};
|
||||
#elif BOARD_MODEL == BOARD_HELTEC32_V4
|
||||
uint8_t buf[4] = {MODE_TCXO_1_8V_6X, 0x00, 0x00, 0xFF};
|
||||
#elif BOARD_MODEL == BOARD_MESHADVENTURER_S3
|
||||
uint8_t buf[4] = {MODE_TCXO_1_8V_6X, 0x00, 0x00, 0xFF};
|
||||
#endif
|
||||
executeOpcode(OP_DIO3_TCXO_CTRL_6X, buf, 4);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user