promicro fixes

This commit is contained in:
liquidraver
2026-09-10 22:40:15 +02:00
parent 69cc148fbe
commit c969b2fca3
3 changed files with 120 additions and 74 deletions
+46 -58
View File
@@ -1,65 +1,41 @@
# ZephCore 1.17.5-zephcore
> [!NOTE]
> **Draft — release in progress.** Covers what is on `dev` so far. More entries will land before this ships.
A Bluetooth range fix that affects every ESP32 board, GPS support on the two Heltec V4 boards, and the
single-button confirmation prompt now works on the eight boards where it never could.
> **Draft — release in progress.** Covers what is on `dev` so far.
---
## Bluetooth range on ESP32 boards was 9 dB down
Every ESP32 board — S3, C-series and classic alike — has been advertising and connecting at 0 dBm.
Stock Arduino MeshCore runs the same radios at +9 dBm. That is the reported "ZephCore has worse
Bluetooth range than the official firmware" on Heltec V4, and the gap is real: 9 dB is roughly 2.8
times the distance in free space.
Nothing was misconfigured. The setting was deliberately left alone, on the understanding that the
Espressif controller blob picked its own transmit power. It does not. Zephyr's driver hands the
controller a default built from a chain of `CONFIG_BT_CTLR_TX_PWR_*` options, and with none of them
set the chain fell through to its `use 0dB TX power as default` arm. Silently, with no warning at
build time and nothing visible on the node.
ESP32 boards now transmit at +9 dBm, matching stock MeshCore. That is comfortably inside the EU
2.4 GHz 100 mW limit, and it is the one level every Espressif chip family in the tree supports, so it
applies everywhere without per-board overrides.
Every ESP32 board has been advertising and connecting at 0 dBm; stock MeshCore runs the same radios
at +9 dBm. Zephyr's driver builds its default from the `CONFIG_BT_CTLR_TX_PWR_*` chain, and with none
of them set it fell through to the 0 dB arm — silently, with nothing visible at build time or on the
node. ESP32 boards now transmit at +9 dBm.
> [!NOTE]
> **Nothing to change on your side.** No setting, no re-pairing. Flash and the range is there.
> nRF52, nRF54L and MG24 boards were never affected — they set their own transmit power already.
> **Nothing to change on your side.** No setting, no re-pairing. nRF52, nRF54L and MG24 were never
> affected — they set their own transmit power.
---
## GPS on Heltec WiFi LoRa 32 V4 and V4.3
Both boards bring a GPS UART and its power-control pins out to the header, and ZephCore had no
wiring for either. Attaching a module did nothing.
They are now described the same way every other GPS board is: NMEA on UART1 at 9600 baud, with the
enable and reset lines driven properly rather than left floating into the module. `set gps on` and
the GPS pages behave as they do elsewhere.
Both boards bring a GPS UART and its power pins out to the header, and ZephCore described neither, so
attaching a module did nothing. They now match every other GPS board: NMEA on UART1 at 9600 baud, with
enable and reset driven rather than left floating.
> [!NOTE]
> **This is for an external module.** Neither board ships with a GPS receiver — the pins are there for
> one you add yourself. Boards with nothing attached are unaffected.
> **For an external module.** Neither board ships with a receiver; boards with nothing attached are
> unaffected.
---
## The confirmation prompt now works on single-button boards
Shutdown, DFU and off-grid all ask you to confirm by pressing ENTER twice. On boards with one button,
ENTER is not a tap — it is a one-second hold, produced by a long-press filter.
Two one-second holds cannot fit inside a half-second window, and half a second is what the window
was. The second hold always arrived after it had closed, so instead of confirming, it re-armed the
prompt. Pressing again did the same thing. On these boards the three actions simply could not be
confirmed from the screen, however many times you tried.
The window is now three seconds on every board that emits ENTER through a long-press filter, which is
what the setting's own documentation had been recommending all along. Six boards had it; eight did not.
Newly fixed:
Shutdown, DFU and off-grid confirm with two ENTER presses. On single-button boards ENTER is a
one-second hold, and the window was half a second — so the second hold always landed too late and
re-armed the prompt instead of confirming. The window is now three seconds on every board that emits
ENTER through a long-press filter. Six had it; eight did not:
| | |
|---|---|
@@ -68,9 +44,7 @@ Newly fixed:
| Heltec WiFi LoRa 32 V4.3 | LilyGo T3-S3 |
| Meshnology W12 | TTGO T-Beam |
> [!NOTE]
> **Boards with a joystick were never affected.** The Wio Tracker L1 and GAT562 use a different menu,
> which has always allowed three seconds. Nothing changes for them.
Joystick boards (Wio Tracker L1, GAT562) use a different menu and were never affected.
Thanks to **bisbille** for finding this and fixing the first two boards.
@@ -78,28 +52,42 @@ Thanks to **bisbille** for finding this and fixing the first two boards.
## Changing frequency or spreading factor now resets adaptive CAD
Adaptive CAD learns a listen-before-talk threshold as an offset from a base value the chip family
publishes per spreading factor and per bandwidth. Change SF or bandwidth and that base moves under
the offset — but the node kept the old offset and, at the next boot, shifted it further to preserve
the absolute threshold it used to name. Correct after a firmware table change, wrong after a preset
change, where the base table's own step is the physics. On an LR1110 the SF7-to-SF12 step alone is
16 counts, enough to slam the offset to its rail: too sensitive and the node defers transmitting on
noise, or too deaf and it transmits over live receptions.
`set radio`, `set freq` and the app's radio settings now perform a full `set cad.reset` whenever they
move frequency, bandwidth or spreading factor — the learned offset and the probe statistics behind it
both belong to the preset you just left. Coding rate is excluded; it changes airtime, not the
threshold. `tempradio` visits its preset at that preset's own base and hands the learned offset back
on revert, without ever writing it to flash; `get cad` shows `a:tmp` while a window is open.
The learned CAD threshold is an offset from a per-SF, per-bandwidth base. Change the preset and the
base moves, but the node kept the old offset — leaving it too sensitive to transmit or too deaf to
defer. `set radio`, `set freq` and the app's radio settings now perform a full `set cad.reset` when
frequency, bandwidth or spreading factor changes. Coding rate is excluded: it changes airtime, not the
threshold. `tempradio` uses its preset's own base and hands the offset back on revert without writing
flash; `get cad` shows `a:tmp` while a window is open.
> [!NOTE]
> **Nothing to change on your side.** The reset is automatic, and the node re-converges in an hour or
> two. Reaching for `set cad.reset` by hand after a preset change is no longer necessary.
> **Nothing to change on your side.** The reset is automatic and the node re-converges in an hour or
> two. `set cad.reset` by hand is no longer needed after a preset change.
Thanks to **Codes** for reporting it.
---
## ProMicro SX1262: Bluetooth dropped every few seconds, and the screen never worked
The nRF52840 SuperMini has no 32.768 kHz crystal, but the board was configured as though it did — so
the Bluetooth controller and the kernel tick ran off a floating oscillator while claiming 50 ppm
accuracy, and the link dropped every few seconds. It now uses the calibrated internal RC at 250 ppm,
matching stock MeshCore's settings for the same silicon. Timing that hangs off the same clock steadies
with it, including the return to receive after a transmission — so repeats of your own message, and
zero-hop ping replies, are no longer missed.
The OLED was never described for this board at all. It is now an SSD1306 on the same I2C pins stock
MeshCore uses, optional at runtime.
> [!NOTE]
> **Check transmit power if your module has no amplifier.** The 10 dBm default is the safe drive level
> for an E22-900M30S. On a bare module (HT-RA62, E22-900M22S) that is your antenna power — 12 dB under
> stock — which reads as no repeats and failed zero-hop pings. `set tx 22` once and it sticks.
Thanks to **Mike's Allotment** for the report.
---
## Also in this release
*To be filled in as further changes land.*
@@ -1,14 +1,53 @@
# ProMicro SX1262 — nRF52840 SuperMini + Ebyte E22-900M30S
# SoftDevice v6 (S140 v6) — NiceNano/SuperMini bootloader uses S140 6.1.1
# 0x00B6 = S140 v6 firmware ID; app partition starts at 0x26000
CONFIG_ZEPHCORE_BOARD_NAME="ProMicro SX1262"
CONFIG_BT_DIS_MODEL_NUMBER_STR="ProMicro SX1262 nRF52840-SX1262"
CONFIG_ZEPHCORE_SD_FWID=0x00B6
# Native Zephyr SX1262 driver (Ebyte E22-900M30S)
CONFIG_ZEPHCORE_RADIO_NATIVE=y
# E22-900M30S has 30dB external PA — default SX1262 output at 10 dBm
# to avoid PA damage on TX. Not capped — user can raise at their own risk.
CONFIG_ZEPHCORE_DEFAULT_TX_POWER_DBM=10
# ProMicro SX1262 — nRF52840 SuperMini + an SX1262 module
# Generic target: built both with the Ebyte E22-900M30S (30 dB PA) and with
# bare no-PA modules (HT-RA62, E22-900M22S). See the TX power note below.
# SoftDevice v6 (S140 v6) — NiceNano/SuperMini bootloader uses S140 6.1.1
# 0x00B6 = S140 v6 firmware ID; app partition starts at 0x26000
CONFIG_ZEPHCORE_BOARD_NAME="ProMicro SX1262"
CONFIG_BT_DIS_MODEL_NUMBER_STR="ProMicro SX1262 nRF52840-SX1262"
CONFIG_ZEPHCORE_SD_FWID=0x00B6
# Native Zephyr SX1262 driver
CONFIG_ZEPHCORE_RADIO_NATIVE=y
# TX power defaults to the SAFE value for the E22-900M30S, whose 30 dB external
# PA is damaged by a hot drive: 10 dBm in, ~30 dBm at the antenna.
#
# This target is also built with bare SX1262 modules that have no PA at all
# (HT-RA62, E22-900M22S). On those, 10 dBm IS the antenna power — 12 dB below
# the 22 dBm official MeshCore ships for the same variant (LORA_TX_POWER=22 in
# variants/promicro/platformio.ini). The symptom is a node close neighbours can
# still hear, that gets zero repeats and fails 0-hop pings to repeaters.
#
# The default stays conservative because the failure modes are not symmetric:
# too little power costs range and is fixable in the app, too much destroys a
# PA permanently. With no external PA, use "set tx 22" after the first flash —
# this is a first-boot pref only, so the new value sticks.
CONFIG_ZEPHCORE_DEFAULT_TX_POWER_DBM=10
# 32.768 kHz source: calibrated RC, not a crystal.
# The nRF52840 SuperMini/ProMicro clones do not fit an LFXO — official MeshCore
# says so outright in variants/promicro/variant.h ("//#define USE_LFXO" /
# "#define USE_LFRC"). Zephyr's default is CLOCK_CONTROL_NRF_K32SRC_XTAL with a
# 50 ppm accuracy claim, so without this the node runs the BLE controller and
# RTC1 (the kernel tick source) off a floating LFXO while telling the peer it is
# 50 ppm accurate: the central's receive windows stop landing on our anchor
# points and the link drops every few seconds, and every k_timer — including the
# LoRa RX duty-cycle windows and the post-TX RX restore — skews with it.
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION=y
# Accuracy claimed to the BLE peer. Zephyr would pick 500 ppm here (its default
# for RC on nRF52); the Adafruit core that stock MeshCore builds on declares
# NRF_CLOCK_LF_ACCURACY_250_PPM for the same calibrated RC on the same silicon
# (libraries/Bluefruit52Lib/src/bluefruit.cpp, alongside rc_ctiv=16 /
# rc_temp_ctiv=2 — what RC_CALIBRATION above provides). Matched to stock so the
# central sizes its receive windows the same way on both firmwares.
CONFIG_CLOCK_CONTROL_NRF_K32SRC_250PPM=y
# Compile in the UI display stack; the OLED panel is optional at runtime.
# SSD1306 on i2c0 (SDA P1.04 / SCL P0.11) — the same bus and pins official
# MeshCore drives via PIN_BOARD_SDA=8 / PIN_BOARD_SCL=7, and it builds every
# ProMicro env with DISPLAY_CLASS=SSD1306Display.
CONFIG_ZEPHCORE_UI_DISPLAY=y
@@ -1,15 +1,18 @@
/*
* ProMicro SX1262 — nRF52840 SuperMini + Ebyte E22-900M30S
* ProMicro SX1262 — nRF52840 SuperMini + SX1262 (generic; see board.conf)
* Copyright (c) 2025 ZephCore
*
* SPDX-License-Identifier: MIT
*
* Hardware:
* - nRF52840 (SuperMini/ProMicro form factor) with BLE 5
* - Ebyte E22-900M30S (SX1262 + 30dB PA), TCXO, DIO2=TXEN, RXEN on P0.17
* - SX1262 module: E22-900M30S (30dB PA) or a bare HT-RA62 / E22-900M22S;
* TCXO, DIO2=TXEN, RXEN on P0.17. TX power differs — see board.conf
* - GPS module on UART0 (9600 baud, P0.22 RX, P0.20 TX)
* - Battery ADC on AIN7 (P0.31), 150K+150K divider (2:1)
* - User button on P1.00, LED on P0.15
* - Optional SSD1306 128x64 OLED on I2C0 @ 0x3c (SDA P1.04, SCL P0.11)
* - No 32.768 kHz crystal fitted — see the K32SRC_RC note in board.conf
* - 3V3 enable on P0.13 (must be HIGH for SX1262 to function)
*/
@@ -30,6 +33,7 @@
zephyr,code-partition = &code_partition;
zephyr,console = &cdc_acm_uart;
zephyr,shell-uart = &cdc_acm_uart;
zephyr,display = &ssd1306;
};
aliases {
@@ -170,6 +174,21 @@
pinctrl-1 = <&i2c0_sleep>;
pinctrl-names = "default", "sleep";
/* SSD1306 OLED — optional; absent panels fail device_is_ready() and are skipped */
ssd1306: ssd1306@3c {
compatible = "solomon,ssd1306";
reg = <0x3c>;
width = <128>;
height = <64>;
segment-offset = <0>;
page-offset = <0>;
display-offset = <0>;
multiplex-ratio = <63>;
segment-remap;
com-invdir;
prechargep = <0x22>;
};
/* All supported environment & power sensors — auto-detected at runtime */
#include "../../common/sensors-i2c.dtsi"
};