Commit Graph
55 Commits
Author SHA1 Message Date
Pieter ViljoenandClaude Opus 5.5 db69172c66 rtc: clear the RV3028 12-hour bit at boot
ZephCore assumed 24-hour mode. If other firmware had left an RV3028 in
12-hour mode, the boot read masked the hours with 0x3F and could restore
a time up to twelve hours off, and each save's 24-hour hours byte meant
a different hour to the chip.

A new optional twelve-hour-bit = [register mask] names the bit, set on
the two RV3028 nodes to Control 2 12_24. Once the chip is cleanly
identified at boot, rtc_probe() clears a set bit and re-reads the time
block; the chip converts its own hours, as MeshCore relies on. If the
register cannot be read, reads FFh, or the clear or re-read fails, no
time is taken from the chip. DS3231/DS1307 are unchanged: a save's hours
byte already selects 24-hour mode there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 07:19:25 -07:00
Pieter ViljoenandClaude Opus 5.5 9b68b7e1ae rtc: write the RTC time only for years 2000-2099
ZephCore writes the year as two BCD digits with no century, as y % 100.
A time before 2000, accepted by a node whose clock had no time yet, was
stored as a year near the end of the century and restored at the next
boot above the 2025 floor: `time 900000000` (1998) came back as 2098.

rtc_time_block() now fails outside 2000-2099, and zephcore_rtc_save()
then logs and writes no time, for every chip; the chip keeps the time it
has. An RV3028 write retry stops if its run-on time leaves the range.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 07:09:40 -07:00
liquidraver 81d98abf2e HLD update 2026-10-06 21:54:36 +02:00
liquidraver 9d6b21a264 comment diet vol.2 2026-10-06 21:43:35 +02:00
liquidraver 8297d88bf7 formatter update, bump and contact iterator fix 2026-10-06 21:24:28 +02:00
liquidraver 9bb7ccfe53 upstream dev sync 2026-10-06 16:59:23 +02:00
liquidraver 108b96d36c rename cli commands and fix it 2026-10-05 22:35:28 +02:00
liquidraver 52644a80a4 make gps standby command universal 2026-10-05 14:00:13 +02:00
liquidraver d5bb275e01 update example board and porting guide 2026-10-05 10:24:36 +02:00
liquidraver 181fd24b22 readme housekeeping 2026-10-04 20:54:33 +02:00
liquidraver f9d01cf33a upstream sync and gps stuff 2026-10-02 23:10:09 +02:00
liquidraver 3b886b861b add seeed lvk + nrf54lm20a 2026-10-02 13:27:21 +02:00
liquidraver 2e0f765036 vanilla dev sync 2026-09-27 16:33:58 +02:00
liquidraver 514aa77fe8 QSPI-bringup stability enhancements 2026-09-27 13:59:33 +02:00
liquidraver 1f1e53d1df Make Packetlogging Great Again 2026-09-27 09:19:49 +02:00
liquidraver d2d786517b power & storage: ESP32 light sleep that sleeps and wakes; less flash wear
ESP32 light sleep (devdocs/lld/13-power-management.md)

Light sleep on the S3 repeaters never worked as designed, for two
independent reasons:

- No S3 repeater ever slept. Every one carries WiFi OTA, the WiFi
  driver starts WiFi at boot (NULL mode), and a started WiFi library
  holds its modem PM lock. Measured on the XIAO: zero sleep entries
  with WiFi compiled in. helpers/pm_esp32_wake.c now stops WiFi at
  boot on PM builds; `start ota` and a station connect start it again
  (verified: AP up, sleep blocked for the session, sleeping after
  `stop ota`).
- DIO1 was not a wake source. GPIO_INT_WAKEUP means EXT1 in Zephyr's
  ESP32 driver: RTC pads only, one trigger polarity for all pins on
  the S3, and pads left on the RTC mux after every sleep. Since 1.17.1
  pm_esp32.overlay also armed the active-low user button; gpio-keys
  configures first, so the driver refused the active-high DIO1.

The new helper arms the radio IRQ line and the user button (sw0) as
per-pin level GPIO wakes (ESP-IDF gpio_wakeup_enable, any pad) for the
length of each sleep, masks their CPU interrupt while in level mode,
and re-raises the interrupt a sleep swallowed through status_w1ts, so
the radio's dio1_isr and gpio-keys run as usual. EXT1 is no longer
used: patch 0003 configures DIO1 as a plain input again and drops the
d7cc4cb pad-restore notifier (preamble section rewritten). Non-RTC
DIO1 boards (XIAO GPIO39, Station G2 GPIO48) can now light-sleep.
Each light sleep is also bounded by the next esp_timer alarm
(pm_policy_next_custom_ticks, CONFIG_PM_CUSTOM_TICKS_HOOK), as ESP-IDF
does; the BLE controller's modem-sleep wake timer lives there.

Light sleep isolates every pad that is not held, RTC or digital, while
the radio keeps receiving. Holds (ESP32_GPIO_SLEEP_HOLD_EN, inert
without PM) now live in each board's own files: NSS and RESET on all
PM-capable boards, VFEM_Ctrl (GPIO7) and Vext on V4/V4.3/V4 R8/WTv2,
CPS on V4, RXEN on the XIAO. The shared overlay keeps only &rtc_timer
and the GPIO wake source; the wrong RTC_PERIPH explanations are gone.

Also:
- `powersaving` (upstream's command and replies) gates light sleep;
  light-sleep builds default to on, and a stored 0 without the new
  pwr_sav_set marker (the field did nothing before) becomes on once.
  `powersaving off` persists and keeps the node (and its USB) awake.
- `get pm`: asleep %, sleeps, wake causes, per-pin wake counts.
- The console window reopens on every user-button press.
- XIAO ESP32-S3: GPIO21 is both the kit's user button and the board's
  led0; the heartbeat drove it low and every sleep woke as a button
  press. led0 is deleted, the button gets a pull-up.
- Station G2: button active-low with pull-up, as upstream reads it
  (was active-high). Untested on hardware.

Verified on the XIAO ESP32-S3 as a light-sleep repeater on the live
mesh (repeat off, 2 dBm) against a T1000-E on the same channel: awake
20 min, ratio of floods heard 0.95; asleep 30.5 min (96.6 % of
uptime), 119 vs 119, ratio 1.00. TX: sent == flood + direct. Heltec
boards: build-only (no unit on the bench).

Companion light sleep stays off by default; the esp_timer bound makes
it possible. Spike on the XIAO (pm_esp32.conf by hand, BLE only): a
held connection survives, 35 min with a poll every minute and no
miss, the SoC asleep ~91 % between connection events, LoRa RX 130 vs
~130 on the T1000-E. Pairing while asleep fails; USB CDC and UI still
need locks before companions can ship with it.

Flash wear (storage)

The companion marked contacts dirty on is_new, but upstream's is_new
means "not in contacts[]": auto-add declined the node (type filter,
hop limit, full table). Every advert from such a node forced a 5 s
full rewrite of an unchanged contacts3, while a contact that really
was just added only got the liveness deadline. onAdvertRecv now
snapshots the stored record first. is_new never dirties. An addition
or a changed name, type or position flushes in 5 s, and a plain
re-advert waits the liveness deadline, now 1 h instead of 10 min.

A new weak hook, zephcore_persist_before_off(), flushes the deferred
writes before every clean reboot and power-off. It is called from
zephcore_power_off(), the ZephyrBoard reboot, bootloader and BLE-OTA
paths, the UI save-and-restart, the joystick restart and wifi_ota.
Off the main thread it posts MESH_EVENT_PERSIST and waits up to 5 s.
Before this, only CMD_REBOOT flushed.

The repeater saved its ACL on every admin login. It now saves only
when the role or secret changed; the secret is the ECDH of two fixed
keys, so re-logins store nothing new. The room server likewise skips
the lazy write unless the role, sync_since or secret changed.
zephcore_prefs_json_save() compares the serialised JSON with the file
and skips an identical rewrite. Not tested on hardware.

Builds and tests: role_builds.sh 10/10; the ESP32 PM set on the
combined tree (five Heltec repeaters, V4 R8, Station G2, XIAO repeater
and companion) 9/9, repeaters at 69-71 % dram0; board_manifest check
clean; host tests quick 114/114. heltec_companion dram0 at 99.80 %
(776 B left, +88 B for both changes together).
2026-09-26 16:49:17 +02:00
liquidraverandClaude Opus 5.5 ffced336fd west: bump Zephyr main to 3e7672a71bd
- retire 0018 (upstream 67151dfaf73 locks the shared multi-heap) and the
  hal_espressif PSRAM-realloc backport (in the new hal pin)
- 0001: add LR1110/LR2021 to LORA_MODULE_BACKEND_NATIVE's depends on;
  upstream 1263266b615 gated it on its own radios and LR boards silently
  fell to loramac-node
- ble: build the persisted gatt_peer settings key ourselves in the old
  format; bt_addr_le_to_str() changed to "P:AA:.." and would have orphaned
  every key and sent every bonded phone a Service Changed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 10:05:36 +02:00
liquidraver 187a44060d close out the restructure's open items
- boot_info: label the ESP32 reset reasons Zephyr's hwinfo driver maps to 0
  (USB-Serial-JTAG/JTAG reset -> DEBUG, power glitch -> BROWNOUT, CPU lockup,
  eFuse -> HARDWARE); get pwrmgt.bootreason no longer says Unknown after a flash
- mqtt: the uplink credentials struct moves to adapters/mqtt/uplink_creds.h,
  so the adapter no longer includes an app header (layout unchanged: the
  struct is persisted raw)
- gps: one off-levels routine for standby/off and System OFF; the sleep line
  stays asserted in standby and drops at System OFF, as upstream's
  sleep_gps/stop_gps/powerOff; System OFF now asserts reset before cutting
  GPS_EN
- doom: sprites solid with a one-pixel black halo, boss drawn 1.5x on the
  floor; the L2 boss was invisible from the spawn on 1-bit panels
2026-09-26 08:50:30 +02:00
liquidraverandClaude Opus 5.5 9fc1eaf18a docs: publish the system design and architecture decision records
DESIGN.md is the reconciled high-level design after the 2026-09 restructure:
system context, roles, build-time composition, layers and dependency rules
(with the known exceptions), threading and event loop, end-to-end flows,
cross-cutting concerns and the upstream alignment policy. docs/adr/ holds the
nine decision records (ESP32 boot layout, S3 native USB, overlay precedence,
BLE privacy, Zephyr main pin, SX126x duty cycle and RX-busy gating, adaptive
contention window, storage backend, WiFi companion boards).
ARCHITECTURE.md stays the detailed component reference and links both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 22:01:28 +02:00
liquidraver 159c086485 repo: publish the host regression suite; consolidate .gitignore
- tests/ (114 host cases over production sources), the CI workflow
  (ASan/UBSan on PRs and master pushes) and REGRESSION_TEST_PLAN.md
  are tracked
- .gitignore grouped and deduplicated (173 -> 96 lines, same ignored set)
2026-09-25 21:56:48 +02:00
liquidraver 059022403b ui: admin telemetry decoder, battery % from board curves, PowerPolicy
- admin screen: telemetry via upstream LPPDataHelpers (ported; fixed its
  1-byte humidity size), every field, per-channel, signed current
  (helpers/ui/telemetry_text)
- battery %: both UIs show ZephyrBoard::getBattPercent() (discharge
  curve / fuel gauge) instead of a linear 3.0-4.2 V estimate
- app/PowerPolicy: low-battery auto-shutdown + v-contact alert +
  autoshutdown CLI on every companion (headless too); under 2000 mV
  counts as no battery; default 3200 mV, stored 3300 migrated once
- one time_sync.c for both UIs; ui_push_radio_state() for all roles
- repeater admin screen in its own file; handleInput split per mode
- dead UI code removed; companion help fits one reply frame
2026-09-25 20:49:48 +02:00
liquidraver d5bd805710 peripherals & power: GPS fixes, poweroff/pwrmgt, upstream SensorManager telemetry
- gps: servers honour gps_enabled at boot (was lost on reboot; zc.gps_set
  upgrades older prefs to on once); sleep lock only while acquiring;
  gps off works on boards without a power line (UART sleep); UI toggles
  and fixes handled on the main thread; configure only after a good init;
  observer parks its GPS; one interval clamp (clampGpsInterval); one
  nav-mode knob (room servers on Air530Z now stationary); GNSS UARTE from DT
- gps: split into ZephyrGPSManager / gps_power / gps_module_cfg
  (+gps_internal.h); dead driver branches, gps_get_diag, sats_* removed
- clock: ZephyrRTCClock writes the hardware RTC itself (clkreboot now
  resets it); MESH_EVENT_RTC_SAVE gone
- power: one power-off path (zephcore_power_off, ZephyrBoard::powerOff),
  poweroff/shutdown CLI, get pwrmgt.*, crash record kept across reboot,
  battery reading cached 10 s, fuel gauge on the current API
- telemetry: upstream SensorManager + CayenneLPP (rounded to nearest),
  one builder for all roles; per-sensor channels, MCU temp always,
  guest gating and inverse mask on servers; sensor list/get/set work;
  BME280/BMP280 also probed at 0x77
- CLI: gps in upstream's form, get gps detail, gps sync
2026-09-25 17:56:34 +02:00
liquidraver 38f815a0a1 server roles, event loops, companion transports, storage and prefs.json
Server roles (slice 7)
- CommonCLI split into upstream's shape; region CLI moved into CommonCLI;
  ClientACL, RegionMap, TransportKeyStore and both server meshes in
  upstream shape over an Arduino compat shim (helpers/compat: Arduino.h,
  Stream/Print, Serial, SHA256, FILESYSTEM/File over Zephyr fs)
- room server processAck port; `get acl` prints as upstream
- room: default name Room-XXXX, display/input rotation, live radio UI refresh

Event loops (slice 7b)
- repeater and room server share server_main_common with a ServerRole
  descriptor; shared event bits in src/mesh_events.h
- room server deadline-driven (idle wakes 2.2/s -> 0.08/s); companion
  loop() runs on housekeeping (closes the lazy contact-flush gap)
- `get loop.wakes` in debug builds (CONFIG_ZEPHCORE_LOOP_WAKE_STATS)

Companion transports and WiFi (slice 8)
- upstream MultiSerialInterface: BLE, USB/UART and TCP are each a
  BaseSerialInterface, every connected transport gets every frame;
  CompanionSerial holds a lossless reply; shared frame_txq for BLE/TCP
- SerialCompanionTransport and LinuxTCPTransport replaced by
  TcpCompanionTransport; ZephyrBLE split (gatt layout, DFU)
- WiFi companion (upstream wifi.ssid/pwd/enabled CLI, TCP port 5000) on
  boards declaring `capabilities: wifi` in zephcore.yml: the PSRAM
  ESP32-S3 boards, plus Heltec V3 (140 contacts), Wireless Tracker (130)
  and both C6 boards (280); ESP32-S3 without PSRAM gets bounded WiFi
  buffers and a measured 72 KB heap; PSRAM boards' internal heap 72 KB
- TCP queues: own depth (ZEPHCORE_TCP_QUEUE_SIZE=8), RX waits instead
  of dropping
- RAM: companion ClientACL dropped; main/BT-TX/TCP stacks sized from
  measured peaks (-7 KB nRF companions, -9 KB ESP32 companions)
- ESP32 WiFi stopped working under ~200 frames/s unicast. Fixed by:
  patches/zephyr/0017 never block the WiFi task in the RX callback;
  patches/zephyr/0018 lock shared_multi_heap (heap corruption with the
  WiFi heap in PSRAM); patches/modules/hal_espressif/0001 backport of
  hal_espressif af97fb02df (PSRAM realloc)

Storage and prefs (slice 9)
- prefs are now prefs.json through upstream's ConfigSerializer (ported
  verbatim), with upstream's key names for shared fields and ZephCore's
  own under "zc"; on first boot the binary new_prefs / repeater prefs is
  migrated and kept, so a downgrade still boots with the old settings
- helpers/PrefsCodec: both legacy binary layouts (companion 272 B,
  server 311 B) as Zephyr-free codecs; sanitizeNodePrefs is the only
  validator
- fix: server prefs could be replaced by a truncated file when a write
  failed; identity, prefs and channel writes go through one checked
  atomic replace (ZephyrFsUtil)
- fix: a corrupt cad_auto byte turned adaptive CAD off instead of the
  default on
- fix: a deliberate 300 s GPS duty on a repeater was rewritten to 48 h
  on every boot (that migration now runs on legacy files only)
- one identity loader for all roles (IdentityFile); an unusable key
  file is always parked as .bad before regenerating
- server store no longer stamps repeater defaults on room server and
  observer; companion first-boot volume policy moved into the store
  (adoptVolume)
- ZephyrDataStore 1435 -> ~850 lines
2026-09-25 08:34:21 +02:00
liquidraver b361c33901 companion: upstream-shaped BaseChatMesh, per-opcode handlers, companion CLI
- BaseChatMesh/ContactInfo/ChannelDetails restored to upstream text, ZephCore
  changes fenced; added to the Shared-file list
- upstream names: handleCmdFrame, writeOKFrame/writeErrFrame,
  addToOfflineQueue, queueMessage; dead dequeue removed
- handleCmdFrame split into handleCmd<Name>() in upstream order;
  CMD_SEND_PATH_DISCOVERY -> _REQ
- CompanionMesh::handleCommand as the single CLI entry point; over-the-air
  TXT_TYPE_CLI_COMMAND from flag-0x10 contacts (upstream command set only)
- V-contact moved to app/VContact.cpp, protocol constants to
  app/CompanionProtocol.h; comment diet (image-identical)
2026-09-24 07:15:44 +02:00
liquidraver 10b36094ae radio: one LoRaRadio adapter over per-family ops tables; lr20xx cleanup
- LoRaRadioBase -> LoRaRadio (final); SX126x/SX127x/LR1110/LR2021Radio
  replaced by const LoRaRadioOps tables (radio_ops_<family>.cpp), one
  linked per build; mains construct the radio in one line
- lr20xx: vendored Semtech SDK + HAL moved beside the driver (no app-tree
  sources), DIO1 handler split (CCN 52 -> 10), zc_lora_timing.h adopted,
  dead exports removed, header rewritten, comment diet (image-identical)
- semtech,lr2021 uses the lr1110 property names (irq-gpios, tcxo-voltage,
  rfsw-*), compiled config byte-identical
- correct the stale "LR2021 is not CAD-probed" claim
2026-09-23 19:51:08 +02:00
liquidraver 0c485b2230 lr11xx: SDK from LoRa Basics Modem, split DIO1 handler, shared LoRa timing
- compile Semtech lr11xx_driver v2.7.0 from modules/lib/lora-basics-modem
  (driver layer only) instead of the vendored fork; HAL moves next to the
  driver (+abort_blocking_cmd); driver no longer builds app-tree sources
- split lr11xx_dio1_work_handler into per-IRQ helpers (CCN 46 -> 12)
- zc_lora_timing.h: preamble grace, payload deadline, 24-bit saturation,
  shared with sx126x (patch 0003) and host-tested; sx126x CAD_RX Rx bound
  now saturates instead of wrapping (SF12/BW7.81)
- semtech,lr1110 binding includes upstream lr11xx-base; boards use
  upstream property names (irq-gpios, tcxo-voltage, rfsw-*)
- drop dead lr11xx_get_random/get_chip_temp_c; correct the IRQ-clear
  invariant wording; comment diet (image-identical)
2026-09-23 19:04:41 +02:00
liquidraver fd2cbe9d62 radio: extract CadController and NoiseFloorEstimator, one prefs source
- CadController (stats, window, re-anchor, visits, staircase, safety,
  starvation relax) and NoiseFloorEstimator split out of LoRaRadioBase
  behind a 4-call CadHw interface; Zephyr-free, host unit tests added
- prefs mandatory: setPrefs() before begin(), LoRaConfig fallbacks and the
  companion/observer placeholder prefs removed; LoRaConfig is the one
  defaults source (invalid-prefs fallback now uses the board TX default)
- TX-wait thread stack owned by the base; reconfigureWithParams removed
- driver extension headers on the public include path
  (zephyr/drivers/lora/*.h); patch 0003 include updated
- comment diet (image-identical); rationale moved to devdocs LLD 03
2026-09-23 14:33:29 +02:00
liquidraver a7d073900e core: restore upstream shape for the shared mesh core
- Mesh, Dispatcher, Packet, packet pool and the core headers rebuilt from
  Arduino MeshCore's text; ZephCore changes re-applied, each fenced
  `// ZEPHCORE:` (diff vs upstream: 4540 -> 1147 lines)
- upstream header layout; MainBoard gains handleCommand/loop and the other
  upstream members; RNG::nextInt back in Utils.cpp
- packet logging moved to the roles' log hooks (helpers/PacketLog.h)
- zero-hop direct ACKs deduplicated and length-checked as upstream
- RadioIncludes.h -> src/, LoRaConfig.h -> helpers/
- .editorconfig: shared files keep upstream formatting

Verified: 10 role builds, per-function disassembly review, bench DM/ACK
regression (T1000-E, Wio L1, XIAO S3 on 1.17.4) incl. via live repeater.
2026-09-23 13:39:48 +02:00
liquidraver 2e2d852f29 build: board manifests, shared board resolver, manifest-driven release matrix
- boards/**/zephcore.yml: one manifest per board/preset (release roles,
  variants, catalog metadata, capabilities); scripts/board_manifest.py
  validates and serves them to build.sh, gen_provider_catalog.py and
  docs/supported_boards.md
- cmake/zephcore_board.cmake: board dir -> platform, shared by app and
  sysbuild; removes the board-name regex lists and 7 separate globs
- conf chain: exact-name role/debug classification checked against
  Kconfig, idempotent across non-pristine reconfigures, version string
  single-sourced (BT DIS rev generated), day-granular build epoch
- Doom easter egg: Kconfig default for the wio_tracker_l1 companion
  instead of a build.sh-only flag
- catalog: maker for the LR2021 EVK (KeyError before); CI installs PyYAML
- user -DEXTRA_DTC_OVERLAY_FILE overlays now take precedence over derived overlays

Verified: identical .config, DTS and source lists for 97 board/role
configs; identical images for 4 reference builds; identical build.sh
command/artifact set and catalog content.
2026-09-23 10:24:40 +02:00
liquidraver 946b871d46 boot reset cause: plain-English hints in the restart notice, fix nrf52840 vbus wake docs 2026-09-19 21:35:22 +02:00
liquidraver 348a6e7fe1 Merge branch 'dev' of https://github.com/liquidraver/ZephCore into dev 2026-09-19 21:20:14 +02:00
liquidraver 0559b065fd Merge pull request #94 from ptr727/boot-reset-cause-capture
capture the reset cause at boot instead of consuming it in main()
2026-09-19 21:15:06 +02:00
liquidraver fb6a303678 ship heltec v4-r8: build.sh, mesh america catalog (folds into heltec v4 tile), trim board docs, display.rotate list 2026-09-19 21:07:39 +02:00
Pieter ViljoenandClaude Opus 5 6ec31e7b7f capture the reset cause at boot instead of consuming it in main()
hwinfo_get_reset_cause() reads a latched register. It was read inline in
main_companion.cpp and cleared there, so the repeater, room server and
observer never read it and never cleared it: their flags carried into the next
boot, and whichever role read first defined what any later reader would see.

helpers/boot_info.c reads it once in a SYS_INIT at POST_KERNEL, logs it,
stores it and clears the register. That runs before main() on every role.
zephcore_boot_reset_cause() hands out the stored copy and reports false where
the platform has no support, which a caller can distinguish from a cause of 0.

The clear's return is discarded deliberately: ESP32 has no
hwinfo_clear_reset_cause() implementation, so the weak stub returns -ENOSYS.
The capture is still correct there; only the next boot's reading is not.

Logging in boot_info_init() rather than only in the consuming role matters
because the clear now happens everywhere. Without it a repeater that rebooted
on WATCHDOG or LOCKUP would have the evidence cleared and recorded nowhere,
where before it survived in the register for whoever read it over SWD.

main_companion.cpp reads the stored copy and renders through a table with one
row per RESET_* bit, so a cause with no label is no longer logged as bare hex.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 11:58:01 -07:00
Pieter ViljoenandClaude Opus 5 43e9db5823 add heltec wifi lora32 v4-r8 board + anchor the esp32 light-sleep allowlist
The V4-R8 is an ESP32-S3R8 with 8 MB octal PSRAM, where V4 and V4.3 are S3R2
with 2 MB quad. Octal PSRAM claims GPIO33-37, which moves Vext 36->40, the LED
35->46 and VGNSS_Ctrl 34->42, and drops ADC_Ctrl and GNSS_RST. CTX binds as
lna-bypass-gpios rather than tx-enable-gpios, so the board is a fourth one
where set radio.fem.rxgain works; the CLI reference and the register-patch help
text say so.

The allowlist change is needed for the board to be added correctly. CMake
MATCHES is a substring search, so the existing heltec_wifi_lora32_v4 entry also
matches heltec_wifi_lora32_v4_r8 and the new board would get CONFIG_PM=y
without anyone deciding it should, on a path pm_esp32.conf marks as not yet
validated on hardware. Anchoring preserves the five boards that were intended
to match, including heltec_wireless_tracker_v2, which previously qualified only
by substring and is now listed explicitly.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-19 09:52:37 -07:00
liquidraver 39b9584b20 .editorconfig and .gitattributes 2026-09-18 21:25:19 +02:00
liquidraver da0450e511 upstream sync + wio tracker 1w 2026-09-16 11:29:45 +02:00
liquidraver 16518e2196 heltec t1 2026-09-14 09:14:46 +02:00
liquidraver 8c21a1609b lr2021 2.4ghz and seeed evk button fix 2026-09-12 19:46:43 +02:00
liquidraver 69cc148fbe properly reset CAD offset when needed 2026-09-10 21:56:52 +02:00
liquidraver eef6a488a2 esp flash fix 2026-09-04 12:14:05 +02:00
liquidraver 1633274e4f leds refactor/improvement 2026-09-03 14:34:12 +02:00
liquidraver 81a43f6dd1 west update and upstream dev sync 2026-09-02 10:01:34 +02:00
liquidraver 1db0a14c4b get cad fix 2026-09-02 08:42:51 +02:00
liquidraver ba33cebf6a cad improvements 2026-09-01 22:05:29 +02:00
liquidraver ccb7fc748d command fixes 2026-08-30 09:27:20 +02:00
liquidraver 7331ca6c58 sync with upstream but held off the companion CLI 2026-08-29 22:08:59 +02:00
liquidraver ca280c52ed vcontact key fix 2026-08-29 21:26:12 +02:00
liquidraver 5bf3c577c9 tune cad detection across all chips 2026-08-29 17:31:39 +02:00
liquidraver 2a519e11d1 try to guard accidental region load command 2026-08-28 10:59:42 +02:00