Unblock LR2021 retunes and add saved crystal calibration

Repeated preamble/header activity can keep a requested primary or TempRadio
change busy indefinitely. Bound unfinished-RX admission for accepted LR2021
changes while preserving completed packets, TX, BUSY and exclusive owners.
Ordinary scans and CAD keep their existing admission rules. Expose the failing
stage and native status through get radio.apply.

Add saved radio.xtrim capacitor calibration and measured radio.freqerror in
signed Hz from the last valid LoRa packet. Preserve native trim by default,
restore explicit calibration after resets/Morse, verify saves before applying,
wait two seconds for the acknowledgement, and roll back failed changes.

Calibration motivation and prior upstream work:
https://github.com/meshcore-dev/MeshCore/issues/3365
https://github.com/recrof/MeshCore/tree/lr2021-trim
Packet-status format follows Semtech's LR20xx driver and RadioLib staging.

Tests execute production activity/admission and transaction paths with noisy
RX, completion races, protected owners, failed setters, RX restart and save
rollback. Physical W12 retuning and RF calibration still require confirmation.
This commit is contained in:
mikecarper committed 2026-10-26 15:55:36 -07:00
1 parent b00d346df7
commit 8a8c80ee6a
32 files changed
+1913 -34

No files matched your search

+51
View File
@@ -2117,6 +2117,17 @@ is free and its reply has drained. No reboot is needed. This ends pending or
active TempRadio sessions. Companion LoRa CLI applies after
its exact reply copies drain; an active TempRadio lease rejects the change.
On LR2021 radios, repeated unfinished preamble/header activity cannot block an
accepted primary or TempRadio change indefinitely. The driver allows one maximum
packet airtime plus a margin, capped at 30 seconds, before stopping an unfinished
reception at the next apply attempt. Completed packets, active transmission,
chip BUSY and exclusive radio tools retain priority. Normal radio2 scanning and
CAD do not use this exception.
If an LR2021 change remains pending, `get radio.apply` reports its admission or
failure stage and native error code. Its frequency field is the driver's last
accepted setting, not a measurement of the transmitted carrier.
**Connections:** USB, browser/TCP/Ethernet CLI, Companion binary command
`0x42` (USB/BLE/TCP), and authorized LoRa CLI. `set freq` saves the frequency;
bandwidth, spreading factor, and coding rate stay as configured. Infrastructure
@@ -2125,6 +2136,46 @@ roles also clamp transmit power to the board's limit for that frequency. Like
---
#### LR2021 frequency measurement and crystal calibration
Available on LR2021 builds, including Meshnology W12:
```text
get radio.freqerror
get radio.xtrim
set radio.xtrim <0-47>[,<0-47>]
set radio.xtrim default
```
`get radio.freqerror` reports the last successfully received LoRa packet's
frequency offset in Hz, its configured frequency and sample age. It reports
`unavailable` before a valid measurement. Failed reads and CRC errors keep the
previous sample and its age. This is the difference between two radios; it does
not establish which radio needs calibration.
`radio.xtrim` adjusts the LR2021 crystal's two load-capacitor codes. A single
number sets both codes; two numbers set XTA and XTB separately. Lower codes
generally raise frequency; each code is a capacitor step, not a fixed Hz offset.
Use a known reference to choose values. TCXO boards reject this setting.
The default leaves the chip's original trim unchanged; no shared calibration
value is imposed on boards. An explicit selection is saved first and waits two
seconds so its acknowledgement can leave with the previous calibration. It then
applies without a reboot when the radio is free, and is restored after resets
and temporary modem changes. A busy radio retries automatically for 30 seconds
after that handoff, including one final admission attempt. If protected radio
work still prevents the change, the
request fails and restores the previous saved selection; `get radio.xtrim`
shows it. A reported radio recovery failure still needs diagnosis.
`set radio.xtrim default` removes the override and resets/reinitializes the radio
to restore its original trim. Node identity and other settings remain saved.
These controls are available through local CLI and authorized LoRa CLI. They do
not change the configured channel frequency shown by `get radio` or `get freq`.
The [Semtech LR20xx driver documents the capacitor range and step size](https://github.com/Lora-net/usp/blob/main/smtc_rac_lib/radio_drivers/lr20xx_driver/inc/lr20xx_system.h).
---
#### View or change this node's rx boosted gain mode (SX12xx and LR1110, v1.14.1+)
**Search terms:** RX boost, receive gain, receiver sensitivity, boosted reception.