Compare commits

..

31 Commits

Author SHA1 Message Date
Ben Meadors
978922296b Increase duration of chirp sound in playChirp 2026-01-08 08:13:57 -06:00
Ben Meadors
01ed5041df Derp 2026-01-08 08:13:16 -06:00
Ben Meadors
71eddb2d29 Fix T-LoRA rotary regression and tighten up playBeep 2026-01-08 07:50:56 -06:00
Wessel
6e110788fd 🔧 Fix LNA/PA power control for Heltec v4, wireless tracker v2 (#9029)
* Fix LNA/PA power control for Heltec v4, wireless tracker v2

* Stop using pin 46 as RF switch, just let DIO2 switch handle the RF path

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2026-01-08 05:42:01 -06:00
Heath Dutton🕴️
86326f294d Fix TSL2591 detection by adding command bit to register read (#9215) 2026-01-08 17:08:41 +11:00
Jonathan Bennett
fb7af18f4f Add needed support bits for the Meshstick (#9042)
* Add needed support bits for the Meshstick

* Portduino: Reduce allowed length by one byte to prevent possible overflow
2026-01-07 23:04:02 -06:00
Jonathan Bennett
4d303c95d1 Add list of text message packet IDs, and check for dupes (#9180)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2026-01-07 16:17:38 -06:00
Ben Meadors
1a6cbb5caa Migrate all of the Meshtastic API attributes into the ini as a source of truth (#9214)
* Migrate all of the Meshtastic API attributes into the ini as a source of truth

* Cleanup garbage coalescing

* Another spot

* We already account for inkhud and mui

* Consolidate

* Removed them

* Boogers

* Infer

* Copying manifest should always succeed

* Remove portduino guards

* Rename

* None
2026-01-07 15:25:38 -06:00
Jason P
70f909d718 Fix Function + M in code (#9200) 2026-01-06 16:02:41 -06:00
Jason P
9c1d55c844 Add option to Mute/Unmute Channel to BaseUI (#9194) 2026-01-06 15:26:45 -06:00
Bob Reese
ba9d0e6fa3 RadioInterface::getRetransmissionMsec now handles encrypted packets correctly (#9184) 2026-01-06 12:34:48 -06:00
santosvivos
9f5170a0bc Add LilyGO T-Beam 1W support (#8967)
* Add LilyGO T-Beam 1W support
- Add board definition and variant files for ESP32-S3 based T-Beam 1W
- Add RF95_FAN_EN support to SX126xInterface for PA cooling fan
- Add SX126X_PA_RAMP_US for configurable PA ramp time (800us for 1W PA)
- Configure RF switch: DIO2 for PA, GPIO 21 for LNA control

* Set TX_GAIN_LORA to 10dB per PR feedback (offset for 1W PA)

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-06 06:23:28 -06:00
Ben Meadors
e648e26c17 Merge pull request #9191 from meshtastic/bme-native
BME680 on Native
2026-01-05 20:55:44 -06:00
Jonathan Bennett
1669a027e6 BME680 on Native
Co-authored-by: juanjin-dev <juanjin.dev@gmail.com>
2026-01-05 19:33:41 -06:00
Ben Meadors
105d657359 Merge pull request #9189 from vidplace7/actions-feature-branches 2026-01-05 16:52:57 -06:00
Austin Lane
37ab800500 Actions: CI for feature/ branches
...and pioarduino
2026-01-05 17:44:07 -05:00
Sergey Galkin
0c553c40d4 Fix zero in sp02 and Heart Rate on screen (#9174)
Fixed zero in sp02 and Heart Rate in HealthTelemetry screen
2026-01-05 07:57:49 +11:00
Iris
17b075a11c added tcxo definition to mesh-tab (#8604) 2026-01-04 05:57:50 -06:00
Valentyn Diduryk
25bdefecb2 Fixed shouldFilterReceived function to check prev relay accoding to the function definition (#9168) 2026-01-04 05:22:26 -06:00
Jorropo
beb268ff25 Revert "add a .clang-format file (#9154)" (#9172)
I thought git would be smart enough to understand all the whitespace changes but even with all the flags I know to make it ignore theses it still blows up if there are identical changes on both sides.

I have a solution but it require creating a new commit at the merge base for each conflicting PR and merging it into develop.

I don't think blowing up all PRs is worth for now, maybe if we can coordinate this for V3 let's say.

This reverts commit 0d11331d18.
2026-01-04 05:15:53 -06:00
Jorropo
0d11331d18 add a .clang-format file (#9154) 2026-01-03 14:19:24 -06:00
Tom Fifield
abab6ce815 Fix link formatting in welcome message (#9163) 2026-01-03 06:00:23 -06:00
brad112358
52907e4c44 Faster rotary encoder events (#9146)
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
2026-01-02 20:22:40 -06:00
Jonathan Bennett
f63dadd19e Add custom coding rate configuration for LoRa (#9155) 2026-01-02 16:23:01 -06:00
Ben Meadors
9313d465f6 I think this is supposed to be extra 2026-01-02 15:58:54 -06:00
Jason P
004746683e Refactored some of the system menus to the new DRY method (Redux) (#9152)
* Refactored some of the system menus to the new DRY method

* Fix menu name from Position to GPS
2026-01-02 15:34:25 -06:00
github-actions[bot]
caceaf424a Automated version bumps (#9030)
Co-authored-by: thebentern <9000580+thebentern@users.noreply.github.com>
2026-01-02 06:56:02 -06:00
Ben Meadors
75144d2028 Update security policy to reflect new stage 2026-01-02 06:42:28 -06:00
Ben Meadors
27b522b55a Merge branch 'master' into develop 2026-01-01 18:25:18 -06:00
renovate[bot]
11b5f1a4fe chore(deps): update dorny/test-reporter action to v2.4.0 (#9135)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-01 18:04:13 -06:00
renovate[bot]
f9c9350f45 chore(deps): update meshtastic/device-ui digest to a8e2f94 (#9140)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-01 18:03:27 -06:00
124 changed files with 1883 additions and 436 deletions

View File

@@ -22,7 +22,7 @@ jobs:
### @{fc-author}, Welcome to Meshtastic! :wave:
Thanks for opening your first issue. If it's helpful, an easy way
to get logs is the "Open Serial Monitor" button on the (Web Flasher](https://flasher.meshtastic.org).
to get logs is the "Open Serial Monitor" button on the [Web Flasher](https://flasher.meshtastic.org).
If you have ideas for features, note that we often debate big ideas
in the [discussions tab](https://github.com/meshtastic/firmware/discussions/categories/ideas)

View File

@@ -8,7 +8,9 @@ on:
branches:
- master
- develop
- pioarduino # Remove when merged // use `feature/` in the future.
- event/*
- feature/*
paths-ignore:
- "**.md"
- version.properties
@@ -18,7 +20,9 @@ on:
branches:
- master
- develop
- pioarduino # Remove when merged // use `feature/` in the future.
- event/*
- feature/*
paths-ignore:
- "**.md"
#- "**.yml"

View File

@@ -143,7 +143,7 @@ jobs:
merge-multiple: true
- name: Test Report
uses: dorny/test-reporter@v2.3.0
uses: dorny/test-reporter@v2.4.0
with:
name: PlatformIO Tests
path: testreport.xml

View File

@@ -4,8 +4,8 @@
| Firmware Version | Supported |
| ---------------- | ------------------ |
| 2.6.x | :white_check_mark: |
| <= 2.5.x | :x: |
| 2.7.x | :white_check_mark: |
| <= 2.6.x | :x: |
## Reporting a Vulnerability

View File

@@ -38,4 +38,4 @@ cp bin/device-install.* $OUTDIR/
cp bin/device-update.* $OUTDIR/
echo "Copying manifest"
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true

View File

@@ -49,4 +49,4 @@ if (echo $1 | grep -q "rak4631"); then
fi
echo "Copying manifest"
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true

View File

@@ -30,4 +30,4 @@ echo "Copying uf2 file"
cp $BUILDDIR/$basename.uf2 $OUTDIR/$basename.uf2
echo "Copying manifest"
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true

View File

@@ -30,4 +30,4 @@ echo "Copying STM32 bin file"
cp $BUILDDIR/$basename.bin $OUTDIR/$basename.bin
echo "Copying manifest"
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json
cp $BUILDDIR/$basename.mt.json $OUTDIR/$basename.mt.json || true

View File

@@ -0,0 +1,14 @@
Lora:
Module: sx1262
CS: 0
IRQ: 6
Reset: 2
Busy: 4
RXen: 1
DIO2_AS_RF_SWITCH: true
spidev: ch341
DIO3_TCXO_VOLTAGE: true
# USB_Serialnum: 12345678
USB_PID: 0x5512
USB_VID: 0x1A86
SX126X_MAX_POWER: 22

View File

@@ -87,6 +87,9 @@
</screenshots>
<releases>
<release version="2.7.18" date="2026-01-02">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.18</url>
</release>
<release version="2.7.17" date="2025-11-28">
<url type="details">https://github.com/meshtastic/firmware/releases?q=tag%3Av2.7.17</url>
</release>

View File

@@ -2,11 +2,12 @@
# trunk-ignore-all(ruff/F821)
# trunk-ignore-all(flake8/F821): For SConstruct imports
import sys
from os.path import join, basename, isfile
from os.path import join
import subprocess
import json
import re
from datetime import datetime
from typing import Dict
from readprops import readProps
@@ -14,8 +15,47 @@ Import("env")
platform = env.PioPlatform()
progname = env.get("PROGNAME")
lfsbin = f"{progname.replace('firmware-', 'littlefs-')}.bin"
manifest_ran = False
def infer_architecture(board_cfg):
try:
mcu = board_cfg.get("build.mcu") if board_cfg else None
except KeyError:
mcu = None
except Exception:
mcu = None
if not mcu:
return None
mcu_l = str(mcu).lower()
if "esp32s3" in mcu_l:
return "esp32-s3"
if "esp32c6" in mcu_l:
return "esp32-c6"
if "esp32c3" in mcu_l:
return "esp32-c3"
if "esp32" in mcu_l:
return "esp32"
if "rp2040" in mcu_l:
return "rp2040"
if "rp2350" in mcu_l:
return "rp2350"
if "nrf52" in mcu_l or "nrf52840" in mcu_l:
return "nrf52840"
if "stm32" in mcu_l:
return "stm32"
return None
def manifest_gather(source, target, env):
global manifest_ran
if manifest_ran:
return
# Skip manifest generation if we cannot determine architecture (host/native builds)
board_arch = infer_architecture(env.BoardConfig())
if not board_arch:
print(f"Skipping mtjson generation for unknown architecture (env={env.get('PIOENV')})")
manifest_ran = True
return
manifest_ran = True
out = []
board_platform = env.BoardConfig().get("platform")
needs_ota_suffix = board_platform == "nordicnrf52"
@@ -47,14 +87,39 @@ def manifest_gather(source, target, env):
manifest_write(out, env)
def manifest_write(files, env):
# Defensive: also skip manifest writing if we cannot determine architecture
def get_project_option(name):
try:
return env.GetProjectOption(name)
except Exception:
return None
def get_project_option_any(names):
for name in names:
val = get_project_option(name)
if val is not None:
return val
return None
def as_bool(val):
return str(val).strip().lower() in ("1", "true", "yes", "on")
def as_int(val):
try:
return int(str(val), 10)
except (TypeError, ValueError):
return None
def as_list(val):
return [item.strip() for item in str(val).split(",") if item.strip()]
manifest = {
"version": verObj["long"],
"build_epoch": build_epoch,
"board": env.get("PIOENV"),
"platformioTarget": env.get("PIOENV"),
"mcu": env.get("BOARD_MCU"),
"repo": repo_owner,
"files": files,
"part": None,
"has_mui": False,
"has_inkhud": False,
}
@@ -69,6 +134,51 @@ def manifest_write(files, env):
if "MESHTASTIC_INCLUDE_INKHUD" in env.get("CPPDEFINES", []):
manifest["has_inkhud"] = True
pioenv = env.get("PIOENV")
device_meta = {}
device_meta_fields = [
("hwModel", ["custom_meshtastic_hw_model"], as_int),
("hwModelSlug", ["custom_meshtastic_hw_model_slug"], str),
("architecture", ["custom_meshtastic_architecture"], str),
("activelySupported", ["custom_meshtastic_actively_supported"], as_bool),
("displayName", ["custom_meshtastic_display_name"], str),
("supportLevel", ["custom_meshtastic_support_level"], as_int),
("images", ["custom_meshtastic_images"], as_list),
("tags", ["custom_meshtastic_tags"], as_list),
("requiresDfu", ["custom_meshtastic_requires_dfu"], as_bool),
("partitionScheme", ["custom_meshtastic_partition_scheme"], str),
("url", ["custom_meshtastic_url"], str),
("key", ["custom_meshtastic_key"], str),
("variant", ["custom_meshtastic_variant"], str),
]
for manifest_key, option_keys, caster in device_meta_fields:
raw_val = get_project_option_any(option_keys)
if raw_val is None:
continue
parsed = caster(raw_val) if callable(caster) else raw_val
if parsed is not None and parsed != "":
device_meta[manifest_key] = parsed
# Determine architecture once; if we can't infer it, skip manifest generation
board_arch = device_meta.get("architecture") or infer_architecture(env.BoardConfig())
if not board_arch:
print(f"Skipping mtjson write for unknown architecture (env={env.get('PIOENV')})")
return
device_meta["architecture"] = board_arch
# Always set requiresDfu: true for nrf52840 targets
if board_arch == "nrf52840":
device_meta["requiresDfu"] = True
device_meta.setdefault("displayName", pioenv)
device_meta.setdefault("activelySupported", False)
if device_meta:
manifest.update(device_meta)
# Write the manifest to the build directory
with open(env.subst("$BUILD_DIR/${PROGNAME}.mt.json"), "w") as f:
json.dump(manifest, f, indent=2)
@@ -166,8 +276,12 @@ def load_boot_logo(source, target, env):
if ("HAS_TFT", 1) in env.get("CPPDEFINES", []):
env.AddPreAction(f"$BUILD_DIR/{lfsbin}", load_boot_logo)
mtjson_deps = ["buildprog"]
if platform.name == "espressif32":
board_arch = infer_architecture(env.BoardConfig())
should_skip_manifest = board_arch is None
# For host/native envs, avoid depending on 'buildprog' (some targets don't define it)
mtjson_deps = [] if should_skip_manifest else ["buildprog"]
if not should_skip_manifest and platform.name == "espressif32":
# Build littlefs image as part of mtjson target
# Equivalent to `pio run -t buildfs`
target_lfs = env.DataToBin(
@@ -175,11 +289,27 @@ if platform.name == "espressif32":
)
mtjson_deps.append(target_lfs)
env.AddCustomTarget(
name="mtjson",
dependencies=mtjson_deps,
actions=[manifest_gather],
title="Meshtastic Manifest",
description="Generating Meshtastic manifest JSON + Checksums",
always_build=False,
)
if should_skip_manifest:
def skip_manifest(source, target, env):
print(f"mtjson: skipped for native environment: {env.get('PIOENV')}")
env.AddCustomTarget(
name="mtjson",
dependencies=mtjson_deps,
actions=[skip_manifest],
title="Meshtastic Manifest (skipped)",
description="mtjson generation is skipped for native environments",
always_build=True,
)
else:
env.AddCustomTarget(
name="mtjson",
dependencies=mtjson_deps,
actions=[manifest_gather],
title="Meshtastic Manifest",
description="Generating Meshtastic manifest JSON + Checksums",
always_build=True,
)
# Run manifest generation as part of the default build pipeline for non-native builds.
env.Default("mtjson")

View File

@@ -18,8 +18,9 @@ def readProps(prefsLoc):
# Try to find current build SHA if if the workspace is clean. This could fail if git is not installed
try:
# Pin abbreviation length to keep local builds and CI matching (avoid auto-shortening)
sha = (
subprocess.check_output(["git", "rev-parse", "--short", "HEAD"])
subprocess.check_output(["git", "rev-parse", "--short=7", "HEAD"])
.decode("utf-8")
.strip()
)

50
boards/t-beam-1w.json Normal file
View File

@@ -0,0 +1,50 @@
{
"build": {
"arduino": {
"ldscript": "esp32s3_out.ld",
"memory_type": "qio_opi"
},
"core": "esp32",
"extra_flags": [
"-DBOARD_HAS_PSRAM",
"-DLILYGO_TBEAM_1W",
"-DARDUINO_USB_CDC_ON_BOOT=1",
"-DARDUINO_USB_MODE=0",
"-DARDUINO_RUNNING_CORE=1",
"-DARDUINO_EVENT_RUNNING_CORE=1"
],
"f_cpu": "240000000L",
"f_flash": "80000000L",
"flash_mode": "qio",
"psram_type": "opi",
"hwids": [
[
"0x303A",
"0x1001"
]
],
"mcu": "esp32s3",
"variant": "t-beam-1w"
},
"connectivity": [
"wifi",
"bluetooth",
"lora"
],
"debug": {
"openocd_target": "esp32s3.cfg"
},
"frameworks": [
"arduino"
],
"name": "LilyGo TBeam-1W",
"upload": {
"flash_size": "16MB",
"maximum_ram_size": 327680,
"maximum_size": 16777216,
"require_upload_port": true,
"speed": 921600
},
"url": "http://www.lilygo.cn/",
"vendor": "LilyGo"
}

6
debian/changelog vendored
View File

@@ -1,3 +1,9 @@
meshtasticd (2.7.18.0) unstable; urgency=medium
* Version 2.7.18
-- GitHub Actions <github-actions[bot]@users.noreply.github.com> Fri, 02 Jan 2026 12:45:36 +0000
meshtasticd (2.7.17.0) unstable; urgency=medium
* Version 2.7.17

View File

@@ -119,7 +119,7 @@ lib_deps =
[device-ui_base]
lib_deps =
# renovate: datasource=git-refs depName=meshtastic/device-ui packageName=https://github.com/meshtastic/device-ui gitBranch=master
https://github.com/meshtastic/device-ui/archive/940ba8570f59c59c3508643f4d72840de716ce20.zip
https://github.com/meshtastic/device-ui/archive/a8e2f947f7abaf0c5ac8e6dd189a22156335beaa.zip
; Common libs for environmental measurements in telemetry module
[environmental_base]

View File

@@ -22,12 +22,19 @@ int BuzzerFeedbackThread::handleInputEvent(const InputEvent *event)
// Handle different input events with appropriate buzzer feedback
switch (event->inputEvent) {
#ifdef INPUTDRIVER_ENCODER_TYPE
case INPUT_BROKER_SELECT:
case INPUT_BROKER_SELECT_LONG:
playClick();
break;
#else
case INPUT_BROKER_USER_PRESS:
case INPUT_BROKER_ALT_PRESS:
case INPUT_BROKER_SELECT:
case INPUT_BROKER_SELECT_LONG:
playBeep(); // Confirmation feedback
playBeep();
break;
#endif
case INPUT_BROKER_UP:
case INPUT_BROKER_UP_LONG:
@@ -58,4 +65,4 @@ int BuzzerFeedbackThread::handleInputEvent(const InputEvent *event)
}
return 0; // Allow other handlers to process the event
}
}

View File

@@ -65,7 +65,7 @@ void playTones(const ToneDuration *tone_durations, int size)
void playBeep()
{
ToneDuration melody[] = {{NOTE_B3, DURATION_1_8}};
ToneDuration melody[] = {{NOTE_B3, DURATION_1_16}};
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
@@ -113,7 +113,14 @@ void playShutdownMelody()
void playChirp()
{
// A short, friendly "chirp" sound for key presses
ToneDuration melody[] = {{NOTE_AS3, 20}}; // Very short AS3 note
ToneDuration melody[] = {{NOTE_AS3, 20}}; // Short AS3 note
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}
void playClick()
{
// A very short "click" sound with minimum delay; ideal for rotary encoder events
ToneDuration melody[] = {{NOTE_AS3, 1}}; // Very Short AS3
playTones(melody, sizeof(melody) / sizeof(ToneDuration));
}

View File

@@ -9,6 +9,7 @@ void playGPSDisableBeep();
void playComboTune();
void playBoop();
void playChirp();
void playClick();
void playLongPressLeadUp();
bool playNextLeadUpNote(); // Play the next note in the lead-up sequence
void resetLeadUpSequence(); // Reset the lead-up sequence to start from beginning

View File

@@ -444,6 +444,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif
#endif
// BME680 BSEC2 support detection
#if !defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
#if defined(RAK_4631) || defined(TBEAM_V10)
#define MESHTASTIC_BME680_BSEC2_SUPPORTED 1
#define MESHTASTIC_BME680_HEADER <bsec2.h>
#else
#define MESHTASTIC_BME680_BSEC2_SUPPORTED 0
#define MESHTASTIC_BME680_HEADER <Adafruit_BME680.h>
#endif // defined(RAK_4631)
#endif // !defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
// -----------------------------------------------------------------------------
// Global switches to turn off features for a minimized build
// -----------------------------------------------------------------------------

View File

@@ -487,7 +487,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
}
break;
case TSL25911_ADDR:
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x12), 1);
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xA0 | 0x12), 1);
if (registerValue == 0x50) {
type = TSL2591;
logFoundDevice("TSL25911", (uint8_t)addr.address);

File diff suppressed because it is too large Load Diff

View File

@@ -128,7 +128,28 @@ template <typename T> struct MenuOption {
MenuOption(const char *labelIn, OptionsAction actionIn) : label(labelIn), action(actionIn), hasValue(false), value() {}
};
struct ScreenColor {
uint8_t r;
uint8_t g;
uint8_t b;
bool useVariant;
ScreenColor(uint8_t rIn = 0, uint8_t gIn = 0, uint8_t bIn = 0, bool variantIn = false)
: r(rIn), g(gIn), b(bIn), useVariant(variantIn)
{
}
};
using RadioPresetOption = MenuOption<meshtastic_Config_LoRaConfig_ModemPreset>;
using LoraRegionOption = MenuOption<meshtastic_Config_LoRaConfig_RegionCode>;
using TimezoneOption = MenuOption<const char *>;
using CompassOption = MenuOption<meshtastic_CompassMode>;
using ScreenColorOption = MenuOption<ScreenColor>;
using GPSToggleOption = MenuOption<meshtastic_Config_PositionConfig_GpsMode>;
using GPSFormatOption = MenuOption<meshtastic_DeviceUIConfig_GpsCoordinateFormat>;
using NodeNameOption = MenuOption<bool>;
using PositionMenuOption = MenuOption<int>;
using ClockFaceOption = MenuOption<bool>;
} // namespace graphics
#endif

View File

@@ -4,6 +4,7 @@
#include "configuration.h"
#include "mesh-pb-constants.h"
#include "meshUtils.h"
#include "modules/TextMessageModule.h"
#if !MESHTASTIC_EXCLUDE_TRACEROUTE
#include "modules/TraceRouteModule.h"
#endif
@@ -35,6 +36,10 @@ bool FloodingRouter::shouldFilterReceived(const meshtastic_MeshPacket *p)
return true; // we handled it, so stop processing
}
if (!seenRecently && !wasUpgraded && textMessageModule) {
seenRecently = textMessageModule->recentlySeen(p->id);
}
if (seenRecently) {
printPacket("Ignore dupe incoming msg", p);
rxDupe++;

View File

@@ -246,7 +246,8 @@ uint32_t RadioInterface::getPacketTime(const meshtastic_MeshPacket *p, bool rece
/** The delay to use for retransmitting dropped packets */
uint32_t RadioInterface::getRetransmissionMsec(const meshtastic_MeshPacket *p)
{
size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded);
size_t numbytes =p->which_payload_variant == meshtastic_MeshPacket_decoded_tag ?
pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded) : p->encrypted.size+MESHTASTIC_HEADER_LENGTH;
uint32_t packetAirtime = getPacketTime(numbytes + sizeof(PacketHeader));
// Make sure enough time has elapsed for this packet to be sent and an ACK is received.
// LOG_DEBUG("Waiting for flooding message with airtime %d and slotTime is %d", packetAirtime, slotTimeMsec);
@@ -520,6 +521,10 @@ void RadioInterface::applyModemConfig()
sf = 12;
break;
}
if (loraConfig.coding_rate >= 5 && loraConfig.coding_rate <= 8 && loraConfig.coding_rate != cr) {
cr = loraConfig.coding_rate;
LOG_INFO("Using custom Coding Rate %u", cr);
}
} else {
sf = loraConfig.spread_factor;
cr = loraConfig.coding_rate;

View File

@@ -113,7 +113,7 @@ bool Router::shouldDecrementHopLimit(const meshtastic_MeshPacket *p)
// Check 3: role check (moderate cost - multiple comparisons)
if (!IS_ONE_OF(node->user.role, meshtastic_Config_DeviceConfig_Role_ROUTER,
meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) {
meshtastic_Config_DeviceConfig_Role_ROUTER_LATE, meshtastic_Config_DeviceConfig_Role_CLIENT_BASE)) {
continue;
}

View File

@@ -53,13 +53,26 @@ template <typename T> bool SX126xInterface<T>::init()
#endif
#if defined(USE_GC1109_PA)
// GC1109 FEM chip initialization
// See variant.h for full pin mapping and control logic documentation
// VFEM_Ctrl (LORA_PA_POWER): Power enable for GC1109 LDO (always on)
pinMode(LORA_PA_POWER, OUTPUT);
digitalWrite(LORA_PA_POWER, HIGH);
// CSD (LORA_PA_EN): Chip enable - must be HIGH to enable GC1109 for both RX and TX
pinMode(LORA_PA_EN, OUTPUT);
digitalWrite(LORA_PA_EN, LOW);
digitalWrite(LORA_PA_EN, HIGH);
// CPS (LORA_PA_TX_EN): PA mode select - HIGH enables full PA during TX, LOW for RX (don't care)
// Note: TX/RX path switching (CTX) is handled by DIO2 via SX126X_DIO2_AS_RF_SWITCH
pinMode(LORA_PA_TX_EN, OUTPUT);
digitalWrite(LORA_PA_TX_EN, LOW);
digitalWrite(LORA_PA_TX_EN, LOW); // Start in RX-ready state
#endif
#ifdef RF95_FAN_EN
digitalWrite(RF95_FAN_EN, HIGH);
pinMode(RF95_FAN_EN, OUTPUT);
#endif
#if ARCH_PORTDUINO
@@ -85,6 +98,13 @@ template <typename T> bool SX126xInterface<T>::init()
power = -9;
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
#ifdef SX126X_PA_RAMP_US
// Set custom PA ramp time for boards requiring longer stabilization (e.g., T-Beam 1W needs >800us)
if (res == RADIOLIB_ERR_NONE) {
lora.setPaRampTime(SX126X_PA_RAMP_US);
}
#endif
// \todo Display actual typename of the adapter, not just `SX126x`
LOG_INFO("SX126x init result %d", res);
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND || res == RADIOLIB_ERR_SPI_CMD_FAILED)
@@ -365,13 +385,13 @@ template <typename T> bool SX126xInterface<T>::sleep()
return true;
}
/** Some boards require GPIO control of tx vs rx paths */
/** Control PA mode for GC1109 FEM - CPS pin selects full PA (txon=true) or bypass mode (txon=false) */
template <typename T> void SX126xInterface<T>::setTransmitEnable(bool txon)
{
#if defined(USE_GC1109_PA)
digitalWrite(LORA_PA_POWER, HIGH);
digitalWrite(LORA_PA_EN, HIGH);
digitalWrite(LORA_PA_TX_EN, txon ? 1 : 0);
digitalWrite(LORA_PA_POWER, HIGH); // Ensure LDO is on
digitalWrite(LORA_PA_EN, HIGH); // CSD=1: Chip enabled
digitalWrite(LORA_PA_TX_EN, txon ? 1 : 0); // CPS: 1=full PA, 0=bypass (for RX, CPS is don't care)
#endif
}

View File

@@ -45,9 +45,9 @@ int SystemCommandsModule::handleInputEvent(const InputEvent *event)
// Mute
case INPUT_BROKER_MSG_MUTE_TOGGLE:
if (moduleConfig.external_notification.enabled && externalNotificationModule) {
externalNotificationModule->setMute(externalNotificationModule->getMute());
externalNotificationModule->setMute(!externalNotificationModule->getMute());
IF_SCREEN(if (!externalNotificationModule->getMute()) externalNotificationModule->stopNow(); screen->showSimpleBanner(
externalNotificationModule->getMute() ? "Notifications\nEnabled" : "Notifications\nDisabled", 3000);)
externalNotificationModule->getMute() ? "Notifications\nDisabled" : "Notifications\nEnabled", 3000);)
}
return 0;
// Bluetooth

View File

@@ -53,7 +53,7 @@ extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const c
#include "Sensor/LTR390UVSensor.h"
#endif
#if __has_include(<bsec2.h>)
#if __has_include(MESHTASTIC_BME680_HEADER)
#include "Sensor/BME680Sensor.h"
#endif
@@ -214,7 +214,7 @@ void EnvironmentTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner)
#if __has_include(<Adafruit_LTR390.h>)
addSensor<LTR390UVSensor>(i2cScanner, ScanI2C::DeviceType::LTR390UV);
#endif
#if __has_include(<bsec2.h>)
#if __has_include(MESHTASTIC_BME680_HEADER)
addSensor<BME680Sensor>(i2cScanner, ScanI2C::DeviceType::BME_680);
#endif
#if __has_include(<Adafruit_BMP280.h>)

View File

@@ -136,12 +136,12 @@ void HealthTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *
display->drawString(x, y += _fontHeight(FONT_SMALL), tempStr);
if (lastMeasurement.variant.health_metrics.has_heart_bpm) {
char heartStr[32];
snprintf(heartStr, sizeof(heartStr), "Heart Rate: %.0f bpm", lastMeasurement.variant.health_metrics.heart_bpm);
snprintf(heartStr, sizeof(heartStr), "Heart Rate: %u bpm", lastMeasurement.variant.health_metrics.heart_bpm);
display->drawString(x, y += _fontHeight(FONT_SMALL), heartStr);
}
if (lastMeasurement.variant.health_metrics.has_spO2) {
char spo2Str[32];
snprintf(spo2Str, sizeof(spo2Str), "spO2: %.0f %%", lastMeasurement.variant.health_metrics.spO2);
snprintf(spo2Str, sizeof(spo2Str), "spO2: %u %%", lastMeasurement.variant.health_metrics.spO2);
display->drawString(x, y += _fontHeight(FONT_SMALL), spo2Str);
}
}

View File

@@ -1,6 +1,6 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(<bsec2.h>)
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(MESHTASTIC_BME680_HEADER)
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "BME680Sensor.h"
@@ -10,6 +10,7 @@
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
int32_t BME680Sensor::runOnce()
{
if (!bme680.run()) {
@@ -17,10 +18,13 @@ int32_t BME680Sensor::runOnce()
}
return 35;
}
#endif // defined(MESHTASTIC_BME680_BSEC2_SUPPORTED)
bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
status = 0;
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
if (!bme680.begin(dev->address.address, *bus))
checkStatus("begin");
@@ -42,12 +46,25 @@ bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
if (status == 0)
LOG_DEBUG("BME680Sensor::runOnce: bme680.status %d", bme680.status);
#else
bme680 = makeBME680(bus);
if (!bme680->begin(dev->address.address)) {
LOG_ERROR("Init sensor: %s failed at begin()", sensorName);
return status;
}
status = 1;
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
initI2CSensor();
return status;
}
bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
if (bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal == 0)
return false;
@@ -65,9 +82,27 @@ bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
// Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms)
measurement->variant.environment_metrics.iaq = bme680.getData(BSEC_OUTPUT_IAQ).signal;
updateState();
#else
if (!bme680->performReading()) {
LOG_ERROR("BME680Sensor::getMetrics: performReading failed");
return false;
}
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.has_gas_resistance = true;
measurement->variant.environment_metrics.temperature = bme680->readTemperature();
measurement->variant.environment_metrics.relative_humidity = bme680->readHumidity();
measurement->variant.environment_metrics.barometric_pressure = bme680->readPressure() / 100.0F;
measurement->variant.environment_metrics.gas_resistance = bme680->readGas() / 1000.0;
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
return true;
}
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
void BME680Sensor::loadState()
{
#ifdef FSCom
@@ -144,5 +179,6 @@ void BME680Sensor::checkStatus(const char *functionName)
else if (bme680.sensor.status > BME68X_OK)
LOG_WARN("%s BME68X code: %d", functionName, bme680.sensor.status);
}
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
#endif

View File

@@ -1,23 +1,40 @@
#include "configuration.h"
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(<bsec2.h>)
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(MESHTASTIC_BME680_HEADER)
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
#include <bme68xLibrary.h>
#include <bsec2.h>
#else
#include <Adafruit_BME680.h>
#include <memory>
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // That's 6 hours worth of millis()
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
const uint8_t bsec_config[] = {
#include "config/bme680/bme680_iaq_33v_3s_4d/bsec_iaq.txt"
};
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
class BME680Sensor : public TelemetrySensor
{
private:
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
Bsec2 bme680;
#else
using BME680Ptr = std::unique_ptr<Adafruit_BME680>;
static BME680Ptr makeBME680(TwoWire *bus) { return std::make_unique<Adafruit_BME680>(bus); }
BME680Ptr bme680;
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
protected:
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
const char *bsecConfigFileName = "/prefs/bsec.dat";
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
uint8_t accuracy = 0;
@@ -34,10 +51,13 @@ class BME680Sensor : public TelemetrySensor
void loadState();
void updateState();
void checkStatus(const char *functionName);
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
public:
BME680Sensor();
#if MESHTASTIC_BME680_BSEC2_SUPPORTED == 1
virtual int32_t runOnce() override;
#endif // MESHTASTIC_BME680_BSEC2_SUPPORTED
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};

View File

@@ -17,6 +17,9 @@ ProcessMessage TextMessageModule::handleReceived(const meshtastic_MeshPacket &mp
auto &p = mp.decoded;
LOG_INFO("Received text msg from=0x%0x, id=0x%x, msg=%.*s", mp.from, mp.id, p.payload.size, p.payload.bytes);
#endif
// add packet ID to the rolling list of packets
textPacketList[textPacketListIndex] = mp.id;
textPacketListIndex = (textPacketListIndex + 1) % TEXT_PACKET_LIST_SIZE;
// We only store/display messages destined for us.
devicestate.rx_text_message = mp;
@@ -47,3 +50,13 @@ bool TextMessageModule::wantPacket(const meshtastic_MeshPacket *p)
{
return MeshService::isTextPayload(p);
}
bool TextMessageModule::recentlySeen(uint32_t id)
{
for (size_t i = 0; i < TEXT_PACKET_LIST_SIZE; i++) {
if (textPacketList[i] != 0 && textPacketList[i] == id) {
return true;
}
}
return false;
}

View File

@@ -1,6 +1,7 @@
#pragma once
#include "Observer.h"
#include "SinglePortModule.h"
#define TEXT_PACKET_LIST_SIZE 50
/**
* Text message handling for Meshtastic.
@@ -19,6 +20,8 @@ class TextMessageModule : public SinglePortModule, public Observable<const mesht
*/
TextMessageModule() : SinglePortModule("text", meshtastic_PortNum_TEXT_MESSAGE_APP) {}
bool recentlySeen(uint32_t id);
protected:
/** Called to handle a particular incoming message
*
@@ -27,6 +30,10 @@ class TextMessageModule : public SinglePortModule, public Observable<const mesht
*/
virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
virtual bool wantPacket(const meshtastic_MeshPacket *p) override;
private:
uint32_t textPacketList[TEXT_PACKET_LIST_SIZE] = {0};
size_t textPacketListIndex = 0;
};
extern TextMessageModule *textMessageModule;

View File

@@ -366,6 +366,14 @@ void portduinoSetup()
cleanupNameForAutoconf("lora-hat-" + std::string(hat_vendor) + "-" + autoconf_product + ".yaml");
} else if (found_ch341) {
product_config = cleanupNameForAutoconf("lora-usb-" + std::string(autoconf_product) + ".yaml");
// look for more data after the null terminator
size_t len = strlen(autoconf_product);
if (len < 74) {
memcpy(portduino_config.device_id, autoconf_product + len + 1, 16);
if (!memfll(portduino_config.device_id, '\0', 16) && !memfll(portduino_config.device_id, 0xff, 16)) {
portduino_config.has_device_id = true;
}
}
}
// Don't try to automatically find config for a device with RAK eeprom.

View File

@@ -64,7 +64,7 @@ class Ch341Hal : public RadioLibHal
void getProductString(char *_product_string, size_t len)
{
len = len > 95 ? 95 : len;
strncpy(_product_string, pinedio.product_string, len);
memcpy(_product_string, pinedio.product_string, len);
}
void init() override {}

View File

@@ -1,5 +1,12 @@
; Port to Disaster Radio's ESP32-v3 Dev Board
[env:meshtastic-dr-dev]
custom_meshtastic_hw_model = 41
custom_meshtastic_hw_model_slug = DR_DEV
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = false
custom_meshtastic_display_name = DR-DEV
custom_meshtastic_tags = DIY
extends = esp32_base
board = esp32doit-devkit-v1
board_level = extra

View File

@@ -1,5 +1,13 @@
; Hydra - Meshtastic DIY v1 hardware with some specific changes
[env:hydra]
custom_meshtastic_hw_model = 39
custom_meshtastic_hw_model_slug = HYDRA
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = Hydra
custom_meshtastic_tags = DIY
extends = esp32_base
board = esp32doit-devkit-v1
build_flags =

View File

@@ -1,5 +1,14 @@
; Meshtastic DIY v1 by Nano VHF Schematic based on ESP32-WROOM-32 (38 pins) devkit & EBYTE E22 SX1262/SX1268 module
[env:meshtastic-diy-v1]
custom_meshtastic_hw_model = 39
custom_meshtastic_hw_model_slug = DIY_V1
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = DIY V1
custom_meshtastic_images = diy.svg
custom_meshtastic_tags = DIY
extends = esp32_base
board = esp32doit-devkit-v1
board_check = true

View File

@@ -38,7 +38,6 @@ build_flags =
-DAXP_DEBUG_PORT=Serial
-DCONFIG_BT_NIMBLE_ENABLED
-DCONFIG_BT_NIMBLE_MAX_BONDS=6 # default is 3
-DCONFIG_BT_NIMBLE_ROLE_CENTRAL_DISABLED
-DCONFIG_NIMBLE_CPP_LOG_LEVEL=2
-DCONFIG_BT_NIMBLE_MAX_CCCDS=20
-DCONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=8192
@@ -61,11 +60,11 @@ lib_deps =
# renovate: datasource=git-refs depName=meshtastic-esp32_https_server packageName=https://github.com/meshtastic/esp32_https_server gitBranch=master
https://github.com/meshtastic/esp32_https_server/archive/3223704846752e6d545139204837bdb2a55459ca.zip
# renovate: datasource=custom.pio depName=NimBLE-Arduino packageName=h2zero/library/NimBLE-Arduino
h2zero/NimBLE-Arduino@2.3.7
h2zero/NimBLE-Arduino@^1.4.3
# renovate: datasource=git-refs depName=libpax packageName=https://github.com/dbinfrago/libpax gitBranch=master
https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip
# renovate: datasource=custom.pio depName=XPowersLib packageName=lewisxhe/library/XPowersLib
lewisxhe/XPowersLib@0.3.2
# renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib
https://github.com/lewisxhe/XPowersLib/archive/v0.3.2.zip
# renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master
https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip
# renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto

View File

@@ -5,4 +5,4 @@ extends = esp32_common
custom_esp32_kind = esp32
build_flags =
${esp32_common.build_flags}
${esp32_common.build_flags}

View File

@@ -1,4 +1,11 @@
[env:heltec-v1]
custom_meshtastic_hw_model = 11
custom_meshtastic_hw_model_slug = HELTEC_V1
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = false
custom_meshtastic_display_name = Heltec V1
custom_meshtastic_tags = Heltec
;build_type = debug ; to make it possible to step through our jtag debugger
extends = esp32_base
board_level = extra

View File

@@ -1,4 +1,11 @@
[env:heltec-v2_1]
custom_meshtastic_hw_model = 10
custom_meshtastic_hw_model_slug = HELTEC_V2_1
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = false
custom_meshtastic_display_name = Heltec V2.1
custom_meshtastic_tags = Heltec
board_level = extra
;build_type = debug ; to make it possible to step through our jtag debugger
extends = esp32_base

View File

@@ -1,4 +1,11 @@
[env:heltec-v2_0]
custom_meshtastic_hw_model = 5
custom_meshtastic_hw_model_slug = HELTEC_V2_0
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = false
custom_meshtastic_display_name = Heltec V2.0
custom_meshtastic_tags = Heltec
;build_type = debug ; to make it possible to step through our jtag debugger
board_level = extra
extends = esp32_base

View File

@@ -1,4 +1,12 @@
[env:m5stack-core]
custom_meshtastic_hw_model = 42
custom_meshtastic_hw_model_slug = M5STACK
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = M5 Stack
custom_meshtastic_tags = M5Stack
extends = esp32_base
board = m5stack-core-esp32
monitor_filters = esp32_exception_decoder

View File

@@ -1,5 +1,13 @@
; The 1.0 release of the nano-g1-explorer board
[env:nano-g1-explorer]
custom_meshtastic_hw_model = 17
custom_meshtastic_hw_model_slug = NANO_G1_EXPLORER
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = Nano G1 Explorer
custom_meshtastic_tags = B&Q
extends = esp32_base
board = ttgo-t-beam
build_flags =

View File

@@ -1,5 +1,13 @@
; The 1.0 release of the nano-g1 board
[env:nano-g1]
custom_meshtastic_hw_model = 14
custom_meshtastic_hw_model_slug = NANO_G1
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = Nano G1
custom_meshtastic_tags = B&Q
extends = esp32_base
board = ttgo-t-beam
build_flags =

View File

@@ -1,4 +1,12 @@
[env:radiomaster_900_bandit_nano]
custom_meshtastic_hw_model = 64
custom_meshtastic_hw_model_slug = RADIOMASTER_900_BANDIT_NANO
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 2
custom_meshtastic_display_name = RadioMaster 900 Bandit Nano
custom_meshtastic_tags = RadioMaster
extends = esp32_base
board = esp32doit-devkit-v1
build_flags =

View File

@@ -1,4 +1,13 @@
[env:rak11200]
custom_meshtastic_hw_model = 13
custom_meshtastic_hw_model_slug = RAK11200
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = RAK WisBlock 11200
custom_meshtastic_images = rak11200.svg
custom_meshtastic_tags = RAK
extends = esp32_base
board = wiscore_rak11200
board_level = pr

View File

@@ -1,5 +1,13 @@
; The 1.0 release of the nano-g1 board
[env:station-g1]
custom_meshtastic_hw_model = 25
custom_meshtastic_hw_model_slug = STATION_G1
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = Station G1
custom_meshtastic_tags = B&Q
extends = esp32_base
board = ttgo-t-beam
build_flags =

View File

@@ -1,5 +1,14 @@
; The 1.0 release of the TBEAM board
[env:tbeam]
custom_meshtastic_hw_model = 4
custom_meshtastic_hw_model_slug = TBEAM
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = LILYGO T-Beam
custom_meshtastic_images = tbeam.svg
custom_meshtastic_tags = LilyGo
extends = esp32_base
board = ttgo-t-beam

View File

@@ -1,5 +1,12 @@
; The original TBEAM board without the AXP power chip and a few other changes
[env:tbeam0_7]
custom_meshtastic_hw_model = 6
custom_meshtastic_hw_model_slug = TBEAM_V0P7
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = false
custom_meshtastic_display_name = LILYGO T-Beam V0.7
custom_meshtastic_tags = LilyGo
board_level = extra
extends = esp32_base
board = ttgo-t-beam

View File

@@ -1,4 +1,11 @@
[env:tlora-v1]
custom_meshtastic_hw_model = 2
custom_meshtastic_hw_model_slug = TLORA_V1
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = false
custom_meshtastic_display_name = LILYGO T-LoRa V1
custom_meshtastic_tags = LilyGo
board_level = extra
extends = esp32_base
board = ttgo-lora32-v1

View File

@@ -1,4 +1,11 @@
[env:tlora-v2]
custom_meshtastic_hw_model = 1
custom_meshtastic_hw_model_slug = TLORA_V2
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = false
custom_meshtastic_display_name = LILYGO T-LoRa V2
custom_meshtastic_tags = LilyGo
board_level = extra
extends = esp32_base
board = ttgo-lora32-v1

View File

@@ -1,4 +1,13 @@
[env:tlora-v2-1-1_6]
custom_meshtastic_hw_model = 3
custom_meshtastic_hw_model_slug = TLORA_V2_1_1P6
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = LILYGO T-LoRa V2.1-1.6
custom_meshtastic_images = tlora-v2-1-1_6.svg
custom_meshtastic_tags = LilyGo
extends = esp32_base
board = ttgo-lora32-v21
board_check = true

View File

@@ -1,4 +1,13 @@
[env:tlora-v2-1-1_8]
custom_meshtastic_hw_model = 15
custom_meshtastic_hw_model_slug = TLORA_V2_1_1P8
custom_meshtastic_architecture = esp32
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = LILYGO T-LoRa V2.1-1.8
custom_meshtastic_images = tlora-v2-1-1_8.svg
custom_meshtastic_tags = LilyGo, 2.4GHz
extends = esp32_base
board_level = extra
board = ttgo-lora32-v21

View File

@@ -4,8 +4,3 @@ custom_esp32_kind = esp32c3
monitor_speed = 115200
monitor_filters = esp32_c3_exception_decoder
build_flags =
${esp32_common.build_flags}
-DCONFIG_BT_NIMBLE_EXT_ADV=1
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2

View File

@@ -1,4 +1,13 @@
[env:heltec-ht62-esp32c3-sx1262]
custom_meshtastic_hw_model = 53
custom_meshtastic_hw_model_slug = HELTEC_HT62
custom_meshtastic_architecture = esp32-c3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Heltec HT62
custom_meshtastic_images = heltec-ht62-esp32c3-sx1262.svg
custom_meshtastic_tags = Heltec
extends = esp32c3_base
board = esp32-c3-devkitm-1
board_level = pr

View File

@@ -1,4 +1,13 @@
[env:m5stack-unitc6l]
custom_meshtastic_hw_model = 111
custom_meshtastic_hw_model_slug = M5STACK_C6L
custom_meshtastic_architecture = esp32-c6
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = M5Stack Unit C6L
custom_meshtastic_images = m5_c6l.svg
custom_meshtastic_tags = M5Stack
extends = esp32c6_base
board = esp32-c6-devkitc-1
;OpenOCD flash method

View File

@@ -1,4 +1,13 @@
[env:CDEBYTE_EoRa-S3]
custom_meshtastic_hw_model = 61
custom_meshtastic_hw_model_slug = CDEBYTE_EORA_S3
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = EBYTE EoRa-S3
custom_meshtastic_tags = EByte
custom_meshtastic_requires_dfu = true
extends = esp32s3_base
board = CDEBYTE_EoRa-S3
build_flags =

View File

@@ -1,4 +1,14 @@
[env:thinknode_m2]
custom_meshtastic_hw_model = 90
custom_meshtastic_hw_model_slug = THINKNODE_M2
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = ThinkNode M2
custom_meshtastic_images = thinknode_m2.svg
custom_meshtastic_tags = Elecrow
custom_meshtastic_requires_dfu = false
extends = esp32s3_base
board = ESP32-S3-WROOM-1-N4
build_flags =

View File

@@ -1,4 +1,14 @@
[env:thinknode_m5]
custom_meshtastic_hw_model = 107
custom_meshtastic_hw_model_slug = THINKNODE_M5
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = ThinkNode M5
custom_meshtastic_images = thinknode_m1.svg
custom_meshtastic_tags = Elecrow
custom_meshtastic_requires_dfu = false
extends = esp32s3_base
board = ESP32-S3-WROOM-1-N4
build_flags =

View File

@@ -75,6 +75,17 @@ build_flags =
-D DISPLAY_SET_RESOLUTION
[env:elecrow-adv-24-28-tft]
custom_meshtastic_hw_model = 97
custom_meshtastic_hw_model_slug = CROWPANEL
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Crowpanel Adv 2.4/2.8 TFT
custom_meshtastic_images = crowpanel_2_4.svg, crowpanel_2_8.svg
custom_meshtastic_tags = Elecrow
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 16MB
extends = crowpanel_small_esp32s3_base
build_flags =
${crowpanel_small_esp32s3_base.build_flags}
@@ -99,6 +110,17 @@ build_flags =
-D LGFX_TOUCH_ROTATION=0
[env:elecrow-adv-35-tft]
custom_meshtastic_hw_model = 97
custom_meshtastic_hw_model_slug = CROWPANEL
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Crowpanel Adv 3.5 TFT
custom_meshtastic_images = crowpanel_3_5.svg
custom_meshtastic_tags = Elecrow
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 16MB
extends = crowpanel_small_esp32s3_base
board_level = pr
build_flags =
@@ -127,6 +149,17 @@ build_flags =
; 4.3, 5.0, 7.0 inch 800x480 IPS (V1)
[env:elecrow-adv1-43-50-70-tft]
custom_meshtastic_hw_model = 97
custom_meshtastic_hw_model_slug = CROWPANEL
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Crowpanel Adv 4.3/5.0/7.0 TFT
custom_meshtastic_images = crowpanel_5_0.svg, crowpanel_7_0.svg
custom_meshtastic_tags = Elecrow
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 16MB
extends = crowpanel_large_esp32s3_base
build_flags =
${crowpanel_large_esp32s3_base.build_flags}

View File

@@ -3,8 +3,3 @@ extends = esp32_common
custom_esp32_kind = esp32s3
monitor_speed = 115200
build_flags =
${esp32_common.build_flags}
-DCONFIG_BT_NIMBLE_EXT_ADV=1
-DCONFIG_BT_NIMBLE_MAX_EXT_ADV_INSTANCES=2

View File

@@ -1,4 +1,14 @@
[env:heltec-v3]
[env:heltec-v3]
custom_meshtastic_hw_model = 43
custom_meshtastic_hw_model_slug = HELTEC_V3
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Heltec V3
custom_meshtastic_images = heltec-v3.svg, heltec-v3-case.svg
custom_meshtastic_tags = Heltec
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = heltec_wifi_lora_32_V3
board_level = pr

View File

@@ -10,6 +10,17 @@ build_flags =
[env:heltec-v4]
custom_meshtastic_hw_model = 110
custom_meshtastic_hw_model_slug = HELTEC_V4
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Heltec V4
custom_meshtastic_images = heltec_v4.svg
custom_meshtastic_tags = Heltec
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 16MB
extends = heltec_v4_base
build_flags =
${heltec_v4_base.build_flags}

View File

@@ -29,10 +29,32 @@
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define USE_GC1109_PA // We have a GC1109 power amplifier+attenuator
#define LORA_PA_POWER 7 // power en
#define LORA_PA_EN 2
#define LORA_PA_TX_EN 46 // enable tx
// ---- GC1109 RF FRONT END CONFIGURATION ----
// The Heltec V4 uses a GC1109 FEM chip with integrated PA and LNA
// RF path: SX1262 -> GC1109 PA -> Pi attenuator -> Antenna
// Measured net TX gain (non-linear due to PA compression):
// +11dB at 0-15dBm input (e.g., 10dBm in -> 21dBm out)
// +10dB at 16-17dBm input
// +9dB at 18-19dBm input
// +7dB at 21dBm input (e.g., 21dBm in -> 28dBm out max)
// Control logic (from GC1109 datasheet):
// Shutdown: CSD=0, CTX=X, CPS=X
// Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF)
// Transmit bypass: CSD=1, CTX=1, CPS=0 (~1dB loss, no PA)
// Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled)
// Pin mapping:
// CTX (pin 6) -> SX1262 DIO2: TX/RX path select (automatic via SX126X_DIO2_AS_RF_SWITCH)
// CSD (pin 4) -> GPIO2: Chip enable (HIGH=on, LOW=shutdown)
// CPS (pin 5) -> GPIO46: PA mode select (HIGH=full PA, LOW=bypass)
// VCC0/VCC1 -> Vfem via U3 LDO, controlled by GPIO7
#define USE_GC1109_PA
#define LORA_PA_POWER 7 // VFEM_Ctrl - GC1109 LDO power enable
#define LORA_PA_EN 2 // CSD - GC1109 chip enable (HIGH=on)
#define LORA_PA_TX_EN 46 // CPS - GC1109 PA mode (HIGH=full PA, LOW=bypass)
// GC1109 FEM: TX/RX path switching is handled by DIO2 -> CTX pin (via SX126X_DIO2_AS_RF_SWITCH)
// GPIO46 is CPS (PA mode), not TX control - setTransmitEnable() handles it in SX126xInterface.cpp
// Do NOT use SX126X_TXEN/RXEN as that would cause double-control of GPIO46
#if HAS_TFT
#define USE_TFTDISPLAY 1

View File

@@ -1,4 +1,15 @@
[env:heltec-vision-master-e213]
custom_meshtastic_hw_model = 67
custom_meshtastic_hw_model_slug = HELTEC_VISION_MASTER_E213
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Heltec Vision Master E213
custom_meshtastic_images = heltec-vision-master-e213.svg
custom_meshtastic_tags = Heltec
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = heltec_vision_master_e213
board_build.partitions = default_8MB.csv

View File

@@ -1,5 +1,16 @@
; Using the original screen class
[env:heltec-vision-master-e290]
custom_meshtastic_hw_model = 68
custom_meshtastic_hw_model_slug = HELTEC_VISION_MASTER_E290
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Heltec Vision Master E290
custom_meshtastic_images = heltec-vision-master-e290.svg
custom_meshtastic_tags = Heltec
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = heltec_vision_master_e290
board_build.partitions = default_8MB.csv

View File

@@ -1,4 +1,15 @@
[env:heltec-vision-master-t190]
custom_meshtastic_hw_model = 66
custom_meshtastic_hw_model_slug = HELTEC_VISION_MASTER_T190
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Heltec Vision Master T190
custom_meshtastic_images = heltec-vision-master-t190.svg
custom_meshtastic_tags = Heltec
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = heltec_vision_master_t190
board_build.partitions = default_8MB.csv

View File

@@ -1,5 +1,15 @@
; Using the original screen class
[env:heltec-wireless-paper]
custom_meshtastic_hw_model = 49
custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_PAPER
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Heltec Wireless Paper
custom_meshtastic_images = heltec-wireless-paper.svg
custom_meshtastic_tags = Heltec
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = heltec_wifi_lora_32_V3
board_build.partitions = default_8MB.csv

View File

@@ -1,4 +1,14 @@
[env:heltec-wireless-paper-v1_0]
custom_meshtastic_hw_model = 57
custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_PAPER_V1_0
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = false
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = Heltec Wireless Paper V1.0
custom_meshtastic_images = heltec-wireless-paper-v1_0.svg
custom_meshtastic_tags = Heltec
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board_level = extra
board = heltec_wifi_lora_32_V3

View File

@@ -1,4 +1,15 @@
[env:heltec-wireless-tracker]
custom_meshtastic_hw_model = 48
custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Heltec Wireless Tracker V1.1
custom_meshtastic_images = heltec-wireless-tracker.svg
custom_meshtastic_tags = Heltec
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv

View File

@@ -1,4 +1,14 @@
[env:heltec-wireless-tracker-V1-0]
custom_meshtastic_hw_model = 58
custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER_V1_0
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = false
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = Heltec Wireless Tracker V1.0
custom_meshtastic_images = heltec-wireless-tracker.svg
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board_level = extra
board = heltec_wireless_tracker

View File

@@ -73,7 +73,29 @@
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define USE_GC1109_PA // We have a GC1109 power amplifier+attenuator
#define LORA_PA_POWER 7 // power en
#define LORA_PA_EN 4
#define LORA_PA_TX_EN 46 // enable tx
// ---- GC1109 RF FRONT END CONFIGURATION ----
// The Heltec Wireless Tracker V2 uses a GC1109 FEM chip with integrated PA and LNA
// RF path: SX1262 -> GC1109 PA -> Pi attenuator -> Antenna
// Measured net TX gain (non-linear due to PA compression):
// +11dB at 0-15dBm input (e.g., 10dBm in -> 21dBm out)
// +10dB at 16-17dBm input
// +9dB at 18-19dBm input
// +7dB at 21dBm input (e.g., 21dBm in -> 28dBm out max)
// Control logic (from GC1109 datasheet):
// Shutdown: CSD=0, CTX=X, CPS=X
// Receive LNA: CSD=1, CTX=0, CPS=X (17dB gain, 2dB NF)
// Transmit bypass: CSD=1, CTX=1, CPS=0 (~1dB loss, no PA)
// Transmit PA: CSD=1, CTX=1, CPS=1 (full PA enabled)
// Pin mapping:
// CTX (pin 6) -> SX1262 DIO2: TX/RX path select (automatic via SX126X_DIO2_AS_RF_SWITCH)
// CSD (pin 4) -> GPIO4: Chip enable (HIGH=on, LOW=shutdown)
// CPS (pin 5) -> GPIO46: PA mode select (HIGH=full PA, LOW=bypass)
// VCC0/VCC1 -> Vfem via U3 LDO, controlled by GPIO7
#define USE_GC1109_PA
#define LORA_PA_POWER 7 // VFEM_Ctrl - GC1109 LDO power enable
#define LORA_PA_EN 4 // CSD - GC1109 chip enable (HIGH=on)
#define LORA_PA_TX_EN 46 // CPS - GC1109 PA mode (HIGH=full PA, LOW=bypass)
// GC1109 FEM: TX/RX path switching is handled by DIO2 -> CTX pin (via SX126X_DIO2_AS_RF_SWITCH)
// GPIO46 is CPS (PA mode), not TX control - setTransmitEnable() handles it in SX126xInterface.cpp
// Do NOT use SX126X_TXEN/RXEN as that would cause double-control of GPIO46

View File

@@ -1,4 +1,14 @@
[env:heltec-wsl-v3]
[env:heltec-wsl-v3]
custom_meshtastic_hw_model = 44
custom_meshtastic_hw_model_slug = HELTEC_WSL_V3
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Heltec Wireless Stick Lite V3
custom_meshtastic_images = heltec-wsl-v3.svg
custom_meshtastic_tags = Heltec
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = heltec_wifi_lora_32_V3
board_build.partitions = default_8MB.csv

View File

@@ -55,5 +55,6 @@
#define SX126X_RESET 14
#define SX126X_RXEN 47
#define SX126X_TXEN RADIOLIB_NC // Assuming that DIO2 is connected to TXEN pin
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#endif

View File

@@ -1,4 +1,12 @@
[env:picomputer-s3]
custom_meshtastic_hw_model = 52
custom_meshtastic_hw_model_slug = PICOMPUTER_S3
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = Pi Computer S3
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = bpi_picow_esp32_s3
board_check = true

View File

@@ -1,4 +1,15 @@
[env:rak3312]
custom_meshtastic_hw_model = 106
custom_meshtastic_hw_model_slug = RAK3312
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = RAK3312
custom_meshtastic_images = rak_3312.svg
custom_meshtastic_tags = RAK
custom_meshtastic_requires_dfu = false
custom_meshtastic_partition_scheme = 16MB
extends = esp32s3_base
board = wiscore_rak3312
board_level = pr
@@ -13,8 +24,7 @@ build_flags =
[env:rak3112]
extends = esp32s3_base
board = wiscore_rak3312
board_level = pr
board_check = true
board_level = extra
upload_protocol = esptool
build_flags =

View File

@@ -1,5 +1,16 @@
; Seeed Studio SenseCAP Indicator
[env:seeed-sensecap-indicator]
custom_meshtastic_hw_model = 70
custom_meshtastic_hw_model_slug = SENSECAP_INDICATOR
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Seeed SenseCAP Indicator
custom_meshtastic_images = seeed-sensecap-indicator.svg
custom_meshtastic_tags = Seeed
custom_meshtastic_partition_scheme = 8MB
= true
extends = esp32s3_base
platform_packages =
platformio/framework-arduinoespressif32 @ https://github.com/mverch67/arduino-esp32/archive/aef7fef6de3329ed6f75512d46d63bba12b09bb5.zip ; add_tca9535 (based on 2.0.16)

View File

@@ -1,4 +1,15 @@
[env:seeed-xiao-s3]
custom_meshtastic_hw_model = 81
custom_meshtastic_hw_model_slug = SEEED_XIAO_S3
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = Seeed Xiao ESP32-S3
custom_meshtastic_images = seeed-xiao-s3.svg
custom_meshtastic_tags = Seeed
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = seeed-xiao-s3
board_level = pr

View File

@@ -1,4 +1,15 @@
[env:station-g2]
custom_meshtastic_hw_model = 31
custom_meshtastic_hw_model_slug = STATION_G2
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 2
custom_meshtastic_display_name = Station G2
custom_meshtastic_images = station-g2.svg
custom_meshtastic_tags = B&Q
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 16MB
extends = esp32s3_base
board = station-g2
board_level = pr

View File

@@ -0,0 +1,25 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define USB_VID 0x303a
#define USB_PID 0x1001
static const uint8_t TX = 43;
static const uint8_t RX = 44;
// I2C for OLED and sensors
static const uint8_t SDA = 8;
static const uint8_t SCL = 9;
// Default SPI mapped to Radio/SD
static const uint8_t SS = 15; // LoRa CS
static const uint8_t MOSI = 11;
static const uint8_t MISO = 12;
static const uint8_t SCK = 13;
// SD Card CS
#define SDCARD_CS 10
#endif /* Pins_Arduino_h */

View File

@@ -0,0 +1,14 @@
; LilyGo T-Beam-1W (1 Watt LoRa with external PA)
[env:t-beam-1w]
extends = esp32s3_base
board = t-beam-1w
board_build.partitions = default_8MB.csv
board_check = true
lib_deps =
${esp32s3_base.lib_deps}
build_flags =
${esp32s3_base.build_flags}
-I variants/esp32s3/t-beam-1w
-D T_BEAM_1W

View File

@@ -0,0 +1,97 @@
// LilyGo T-Beam-1W variant.h
// Configuration based on LilyGO utilities.h and RF documentation
// I2C for OLED display (SH1106 at 0x3C)
#define I2C_SDA 8
#define I2C_SCL 9
// GPS - Quectel L76K
#define GPS_RX_PIN 5
#define GPS_TX_PIN 6
#define GPS_1PPS_PIN 7
#define GPS_WAKEUP_PIN 16 // GPS_EN_PIN in LilyGO code
#define HAS_GPS 1
#define GPS_BAUDRATE 9600
// Buttons
#define BUTTON_PIN 0 // BUTTON 1
#define BUTTON_PIN_ALT 17 // BUTTON 2
// SPI (shared by LoRa and SD)
#define SPI_MOSI 11
#define SPI_SCK 13
#define SPI_MISO 12
#define SPI_CS 10
// SD Card
#define HAS_SDCARD
#define SDCARD_USE_SPI1
#define SDCARD_CS SPI_CS
// LoRa Radio - SX1262 with 1W PA
#define USE_SX1262
#define LORA_SCK SPI_SCK
#define LORA_MISO SPI_MISO
#define LORA_MOSI SPI_MOSI
#define LORA_CS 15
#define LORA_RESET 3
#define LORA_DIO1 1
#define LORA_BUSY 38
// CRITICAL: Radio power enable - MUST be HIGH before lora.begin()!
// GPIO 40 powers the SX1262 + PA module via LDO
#define SX126X_POWER_EN 40
// TX power offset for external PA (0 = no offset, full SX1262 power)
#define TX_GAIN_LORA 10
#ifdef USE_SX1262
#define SX126X_CS LORA_CS
#define SX126X_DIO1 LORA_DIO1
#define SX126X_BUSY LORA_BUSY
#define SX126X_RESET LORA_RESET
// RF switching configuration for 1W PA module
// DIO2 controls PA (via SX126X_DIO2_AS_RF_SWITCH)
// CTRL PIN (GPIO 21) controls LNA - must be HIGH during RX
// Truth table: DIO2=1,CTRL=0 → TX (PA on, LNA off)
// DIO2=0,CTRL=1 → RX (PA off, LNA on)
#define SX126X_DIO2_AS_RF_SWITCH
#define SX126X_RXEN 21 // LNA enable - HIGH during RX
// TCXO voltage - required for radio init
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
#define SX126X_MAX_POWER 22
#endif
// LED
#define LED_PIN 18
#define LED_STATE_ON 1 // HIGH = ON
// Battery ADC
#define BATTERY_PIN 4
#define ADC_CHANNEL ADC1_GPIO4_CHANNEL
#define BATTERY_SENSE_SAMPLES 30
#define ADC_MULTIPLIER 2.9333
// NTC temperature sensor
#define NTC_PIN 14
// Fan control
#define FAN_CTRL_PIN 41
// Meshtastic standard fan control pin macro
#define RF95_FAN_EN FAN_CTRL_PIN
// PA Ramp Time - T-Beam 1W requires >800us stabilization (default is 200us)
// Value 0x05 = RADIOLIB_SX126X_PA_RAMP_800U
#define SX126X_PA_RAMP_US 0x05
// Display - SH1106 OLED (128x64)
#define USE_SH1106
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
// 32768 Hz crystal present
#define HAS_32768HZ 1

View File

@@ -1,4 +1,15 @@
[env:t-deck-pro]
custom_meshtastic_hw_model = 102
custom_meshtastic_hw_model_slug = T_DECK_PRO
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = LILYGO T-Deck Pro
custom_meshtastic_images = tdeck_pro.svg
custom_meshtastic_tags = LilyGo
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 16MB
extends = esp32s3_base
board = t-deck-pro
board_check = true

View File

@@ -1,5 +1,16 @@
; LilyGo T-Deck
[env:t-deck]
custom_meshtastic_hw_model = 50
custom_meshtastic_hw_model_slug = T_DECK
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = LILYGO T-Deck
custom_meshtastic_images = t-deck.svg
custom_meshtastic_tags = LilyGo
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 16MB
extends = esp32s3_base
board = t-deck
board_check = true

View File

@@ -1,5 +1,15 @@
; LilyGo T-Watch S3
[env:t-watch-s3]
custom_meshtastic_hw_model = 51
custom_meshtastic_hw_model_slug = T_WATCH_S3
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = LILYGO T-Watch S3
custom_meshtastic_images = t-watch-s3.svg
custom_meshtastic_tags = LilyGo
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = t-watch-s3
board_check = true

View File

@@ -1,5 +1,16 @@
; The 1.0 release of the LilyGo TBEAM-S3-Core board
[env:tbeam-s3-core]
custom_meshtastic_hw_model = 12
custom_meshtastic_hw_model_slug = LILYGO_TBEAM_S3_CORE
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = LILYGO T-Beam Supreme
custom_meshtastic_images = tbeam-s3-core.svg
custom_meshtastic_tags = LilyGo
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = tbeam-s3-core
board_build.partitions = default_8MB.csv

View File

@@ -1,5 +1,16 @@
; LilyGo T-Lora-Pager
[env:tlora-pager]
custom_meshtastic_hw_model = 103
custom_meshtastic_hw_model_slug = T_LORA_PAGER
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = LILYGO T-LoRa Pager
custom_meshtastic_images = lilygo-tlora-pager.svg
custom_meshtastic_tags = LilyGo
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 16MB
extends = esp32s3_base
board = t-deck-pro ; same as T-Deck Pro
board_check = true

View File

@@ -1,4 +1,14 @@
[env:tlora-t3s3-epaper]
custom_meshtastic_hw_model = 16
custom_meshtastic_hw_model_slug = TLORA_T3_S3
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = LILYGO T-LoRa T3-S3 E-Ink
custom_meshtastic_images = tlora-t3s3-epaper.svg
custom_meshtastic_tags = LilyGo
custom_meshtastic_requires_dfu = true
extends = esp32s3_base
board = tlora-t3s3-v1
board_check = true

View File

@@ -1,4 +1,14 @@
[env:tlora-t3s3-v1]
custom_meshtastic_hw_model = 16
custom_meshtastic_hw_model_slug = TLORA_T3_S3
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = LILYGO T-LoRa T3-S3
custom_meshtastic_images = tlora-t3s3-v1.svg
custom_meshtastic_tags = LilyGo
custom_meshtastic_requires_dfu = true
extends = esp32s3_base
board = tlora-t3s3-v1
board_check = true

View File

@@ -1,4 +1,13 @@
[env:tracksenger]
custom_meshtastic_hw_model = 48
custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = TrackSenger (small TFT)
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv
@@ -16,6 +25,15 @@ lib_deps =
lovyan03/LovyanGFX@1.2.7
[env:tracksenger-lcd]
custom_meshtastic_hw_model = 48
custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = false
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = TrackSenger (big TFT)
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv
@@ -33,6 +51,14 @@ lib_deps =
lovyan03/LovyanGFX@1.2.7
[env:tracksenger-oled]
custom_meshtastic_hw_model = 48
custom_meshtastic_hw_model_slug = HELTEC_WIRELESS_TRACKER
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = TrackSenger (big OLED)
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = heltec_wireless_tracker
board_build.partitions = default_8MB.csv

View File

@@ -1,6 +1,15 @@
; platformio.ini for unphone meshtastic
[env:unphone]
custom_meshtastic_hw_model = 59
custom_meshtastic_hw_model_slug = UNPHONE
custom_meshtastic_architecture = esp32-s3
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = unPhone
custom_meshtastic_requires_dfu = true
custom_meshtastic_partition_scheme = 8MB
extends = esp32s3_base
board = unphone
board_build.partitions = partition-table-8MB.csv

View File

@@ -34,6 +34,8 @@ lib_deps =
adafruit/Adafruit seesaw Library@1.7.9
# renovate: datasource=git-refs depName=RAK12034-BMX160 packageName=https://github.com/RAKWireless/RAK12034-BMX160 gitBranch=main
https://github.com/RAKWireless/RAK12034-BMX160/archive/dcead07ffa267d3c906e9ca4a1330ab989e957e2.zip
# renovate: datasource=custom.pio depName=adafruit/Adafruit BME680 Library packageName=adafruit/library/Adafruit BME680
adafruit/Adafruit BME680 Library@^2.0.5
build_flags =
${arduino_base.build_flags}

View File

@@ -1,5 +1,14 @@
; First prototype eink/nrf52840/sx1262 device
[env:thinknode_m1]
custom_meshtastic_hw_model = 89
custom_meshtastic_hw_model_slug = THINKNODE_M1
custom_meshtastic_architecture = nrf52840
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = ThinkNode M1
custom_meshtastic_images = thinknode_m1.svg
custom_meshtastic_tags = Elecrow
extends = nrf52840_base
board = ThinkNode-M1
board_check = true

View File

@@ -1,8 +1,17 @@
[env:thinknode_m3]
custom_meshtastic_support_level = 1
custom_meshtastic_images = thinknode_m3.svg
custom_meshtastic_tags = Elecrow
extends = nrf52840_base
board = ThinkNode-M3
board_check = true
debug_tool = jlink
custom_meshtastic_hw_model = 115
custom_meshtastic_hw_model_slug = THINKNODE_M3
custom_meshtastic_architecture = nrf52840
custom_meshtastic_display_name = Elecrow ThinkNode M3
custom_meshtastic_actively_supported = true
build_flags =
${nrf52840_base.build_flags}
-Ivariants/nrf52840/ELECROW-ThinkNode-M3

View File

@@ -1,5 +1,14 @@
; ThinkNode M6 - Outdoor Solar Power nrf52840/sx1262 device
[env:thinknode_m6]
custom_meshtastic_hw_model = 120
custom_meshtastic_hw_model_slug = THINKNODE_M6
custom_meshtastic_architecture = nrf52840
custom_meshtastic_actively_supported = false
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = ThinkNode M6
custom_meshtastic_images = thinknode_m6.svg
custom_meshtastic_tags = Elecrow
extends = nrf52840_base
board = ThinkNode-M6
board_check = true

View File

@@ -1,5 +1,13 @@
; Public Beta oled/nrf52840/sx1262 device
[env:canaryone]
custom_meshtastic_hw_model = 29
custom_meshtastic_hw_model_slug = CANARYONE
custom_meshtastic_architecture = nrf52840
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = Canary One
custom_meshtastic_tags = Canary
extends = nrf52840_base
board = canaryone
debug_tool = jlink

View File

@@ -1,5 +1,15 @@
; Promicro + E22(0)-xxxM / HT-RA62 modules board variant - DIY - with TCXO
[env:nrf52_promicro_diy_tcxo]
custom_meshtastic_hw_model = 63
custom_meshtastic_hw_model_slug = NRF52_PROMICRO_DIY
custom_meshtastic_architecture = nrf52840
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 3
custom_meshtastic_display_name = NRF52 Pro-micro DIY
custom_meshtastic_images = promicro.svg
custom_meshtastic_tags = DIY
custom_meshtastic_requires_dfu = true
extends = nrf52840_base
board = promicro-nrf52840
build_flags = ${nrf52840_base.build_flags}

View File

@@ -1,5 +1,14 @@
; First prototype nrf52840/sx1262 device
[env:heltec-mesh-node-t114]
custom_meshtastic_hw_model = 69
custom_meshtastic_hw_model_slug = HELTEC_MESH_NODE_T114
custom_meshtastic_architecture = nrf52840
custom_meshtastic_actively_supported = true
custom_meshtastic_support_level = 1
custom_meshtastic_display_name = Heltec Mesh Node T114
custom_meshtastic_images = heltec-mesh-node-t114.svg, heltec-mesh-node-t114-case.svg
custom_meshtastic_tags = Heltec
extends = nrf52840_base
board = heltec_mesh_node_t114
board_level = pr

Some files were not shown because too many files have changed in this diff Show More