One nRF52840 variant shared across both radios, picked per env: Duo runs
the LR1121, Uno the SX1262. Same PCB, only the radio and its DIO1 pin
change.
SuperIO adds the SH1107 OLED, GPS, buzzer and joystick. GPS is driven by
the 3-position mode switch (Mode 2 = on), polled live the way thinknode_m1
does it.
Five quick user-button presses power the unit off; a press wakes it back
on (arms the button as an nRF52 GPIO SENSE source before SYSTEMOFF).
Consolidates #2054 and andyshinn's shared-base/uno work, rebased on dev.
Co-authored-by: lbibass <ewdries02@gmail.com>
Co-authored-by: Andy Shinn <andys@andyshinn.as>
boards/tracker-t1000-e.json set the application's usb_product to
"T1000-E-BOOT". PlatformIO's nordicnrf52 builder turns that key into
-DUSB_PRODUCT, which lands in the USB device descriptor, so a running
node enumerates as "T1000-E-BOOT" while the Seeed bootloader enumerates
as "T1000-E". The firmware that is not the bootloader is the one wearing
the bootloader's name.
That misidentification is load-bearing in the web flasher.
flasher.meshcore.io calls navigator.serial.requestPort() with no filters,
so the row label in the browser's port chooser -- which the browser builds
from the USB iProduct string -- is the only signal the user has. The nRF52
flow prompts twice, once for the 1200-baud DFU touch and again for the
flash itself, with no re-enumeration watcher in between, and at that
second prompt the two candidate rows read:
T1000-E-BOOT (239a:8029) <- the application
T1000-E (2886:0057) <- the actual bootloader
which is backwards at the moment the user has to tell them apart.
The same define is also the Adafruit core's CFG_DEFAULT_NAME, so it is
what a companion advertises over BLE whenever the intended name is too
long for the GAP device-name attribute and setName() silently fails
(#1769). The string is user-visible over Bluetooth as well.
Name the application after the firmware it runs rather than after the
board. This deliberately differs from the hardware-name convention in the
other nRF52 board files ("WisCore RAK4631 Board", "Seeed Wio Tracker L1")
because the string's job here is to distinguish the running application
from a bootloader that will never claim to be MeshCore; "Seeed T1000-E"
would sit one word away from the bootloader's "T1000-E".
Upload and flashing are unaffected -- PlatformIO's port autodetect matches
on hwids (VID:PID), not on this string. On Linux the /dev/serial/by-id
symlink does change, from usb-Seeed_Studio_T1000-E-BOOT_<serial>-if00 to
usb-Seeed_Studio_MeshCore_T1000-E_<serial>-if00, so anything pinned to the
old path needs updating.
First upstream merge since the 2026-06-06 base (191 upstream commits). 14 files
conflicted; resolutions below.
Fleet-critical check (Constraint 1): upstream reordered NodePrefs members
(rx_boosted_gain / path_hash_mode moved to the struct tail) but did NOT change
/com_prefs. Persistence is written field-by-field at explicit offsets, so member
order is in-memory only. Verified the fork's writeCommonPrefsImage() is
byte-identical to upstream's inline writer at every offset (79 pad, 121, 122,
290-294). No migration needed.
Resolutions:
- CommonCLI.h: kept the fork's NodePrefs (superset) and adopted upstream's
setRxBoostedGain(bool)->bool signature change, which CommonCLI.cpp now uses to
report unsupported. Corrected a stale comment claiming rx_boosted_gain lives at
offset 79 (it is a pad; the field is at 290).
- CommonCLI.cpp: kept the fork's legacy /com_prefs migration and the extracted
writeCommonPrefsImage() call.
- UITask.cpp: three-way merge - upstream's drawTextCentered + powering-off
screen, plus the fork's WITH_WEBCONFIG portal/reboot screens.
- ESP32Board.cpp, MeshCore.h, platformio.ini: kept both sides (fork OTA additions
alongside upstream powerOff/enterDeepSleep and Packet.cpp).
- MicroNMEALocationProvider.h: took upstream's claim/release and added the
_claims member they depend on.
- MyMesh.cpp/.h (repeater + room server): kept the fork's superset defaults.
- Removed duplicate declarations auto-merge produced: RadioLibWrapper::_cad_enabled
and MyMesh::getCADEnabled().
Verification: native suite 15/15 (incl. upstream's new test_mesh_tables), both
MQTT smoke builds green, ArduinoJson pin check passes. Hardware validation next.
Credit: @yellowcooln (PR #12). Adds Wireless Tracker v1.1 board
def and MQTT observer envs for v1.1/v2; gate FEM control so v1.1
builds without KCT8103L pins.
Integrates Mike Carper's transmission-reliability work (direct retries with
SNR-adaptive backoff and CR, flood retry controls, alt-path replies, flood
channel gates) plus its upstream/dev base (as of 2026-07-06) on top of the
observer stack. The flex branch is untouched; this branch is the experimental
integration line.
Conflict-resolution decisions, for future re-syncs (git rerere is enabled and
has recorded these):
- NodePrefs adopts keymind/upstream member order + retry/flood tail. Member
order is in-memory only: /com_prefs stays field-by-field with the same
canonical file order both sides already share through offset 294; keymind
appends the retry tail at 295+ (new canonical size 676). Flex fleet files
load unchanged; retry fields default via direct_retry_prefs_magic.
- loadPrefsInt keeps the fork's legacy MQTT-gap recovery but moves its
detection boundary from 'extra > 5' to 'extra > LEGACY_MQTT_GAP_3SLOT (864)'
so keymind-size tails take the normal read path. COM_PREFS_TAIL_BYTES
retired.
- Dispatcher/RadioLibWrappers: fork watchdog additions + keymind TX overrides
and CAD busy counter are unioned; RxReservePacketManager::queueOutbound
follows upstream's new bool return (false when shedding).
- CommonCLI: fork observer dispatch + versioned /mqtt_prefs machinery kept;
keymind CLI (retry/flood/radioat) taken; duplicate CAD/FEM handlers and
sanitise lines deduped (kept keymind placements to minimize future diff).
- MyMesh (repeater/room): fork alerter/OTA/observer wiring kept; keymind
scheduled-radio system replaces the old pending_* temp-radio members;
applySavedRadioParams() replaces raw setParams at startup.
- ESP32Board: fork manifest-OTA + keymind powerOff/deepSleep and stopOTAUpdate
unioned; startOTAUpdate keeps fork's STA-aware IP with keymind's idempotency
guard.
- build.sh taken wholesale from keymind (fleet builds use GH Actions).
Verified: Heltec_v3_repeater_observer_mqtt, Heltec_v3_repeater,
heltec_v4_repeater_observer_mqtt, Heltec_v3_room_server_observer_mqtt build;
host migration harness (13 MQTT + non-MQTT scenarios) passes with updated
expectations (676-byte /com_prefs; odd-size files normalize on save, not
load); native unit tests 13/13.
Added support for `LilyGo_TBeam_1W_repeater_observer_mqtt` and `LilyGo_TBeam_1W_room_server_observer_mqtt` in the MQTT implementation documentation. Updated partition table references to `default_16MB.csv` for these observers, clarifying the requirements for flashing firmware and the implications for stored settings. Enhanced the platformio configuration for both observer types, including build flags and dependencies.