Use 4.6-chirp minimum dwell for both radio profiles
This commit is contained in:
1 parent
b5440c75c7
commit
239f6a84f5
14 files changed
+545
-70
No files matched your search
@@ -0,0 +1,62 @@
|
||||
# Automatic dwell policy: 4.6 chirps on both profiles
|
||||
|
||||
The shared `RadioProfiles` function uses a 4.6-symbol minimum for both logical
|
||||
profiles of one physical transceiver, rounded upward to a whole microsecond.
|
||||
The slower profile is selected by symbol duration, with primary winning ties.
|
||||
The fast visit receives the remaining half-slow-preamble budget, subject to
|
||||
the same 4.6-symbol minimum. The nominal allowances are 600 us per switch and
|
||||
300 us per cycle, not added delays.
|
||||
|
||||
The scheduler, automatic preambles, configuration acceptance and diagnostic
|
||||
calculator use the same minima. Preserve explicit preambles, safe-airtime
|
||||
validation, too-short slow-preamble rejection, recommendation rounding to
|
||||
multiples of eight (minimum 32), and the existing SF8/500 versus SF7/62.5
|
||||
88-symbol recommendation floor. Measured switching overruns raise advisory
|
||||
warnings without rewriting configured values. Single-profile RX still does
|
||||
not perform a scan.
|
||||
|
||||
For SF7/62.5 plus SF8/500 with slow preamble 32, the allocation remains
|
||||
9,421 us slow and 21,847 us fast, in either profile order. The fast visit
|
||||
already exceeds 4.6 fast symbols. Raising the fast minimum matters when
|
||||
less budget is available: equal SF7/500 profiles with slow preamble 30 no
|
||||
longer fit, because only 1,162 us would remain versus the new 1,178 us floor.
|
||||
Slow preamble 32 fits with a 1,418 us fast visit.
|
||||
|
||||
## Hardware context
|
||||
|
||||
The preceding V4 RX / fixed RAK4631 and T1000-E TX bench used explicit
|
||||
32-symbol preambles on both profiles, 100 stationary controls per profile
|
||||
and a complete 100/profile scan. Controls passed 100/100 each; scanning
|
||||
received slow 97/100 and fast 100/100 (197/200 total). Switching averaged
|
||||
582 us and peaked at 827 us. Successful-packet mean SNR was +12.27/+13.47 dB.
|
||||
No RF retry or USB result replay was used. Radios were left idle.
|
||||
|
||||
That test used the same 9,421/21,847 us windows, so the higher fast floor
|
||||
does not change this particular allocation. It does not establish lossless
|
||||
performance or qualify other SF/BW combinations. Raw capture SHA-256:
|
||||
`1c2e0eae3f304fcaeb6addfeef4f2f09a3c2bec8d78c60d3f151c952d0f6d5f5`.
|
||||
No additional RF run is required to apply the user-requested policy change.
|
||||
|
||||
## Software verification
|
||||
|
||||
The portable C++ test sweeps 1,600 SF/BW pairs and checks both 4.6-symbol
|
||||
minima, exact fast-window allocation, preamble/diagnostic consistency and
|
||||
accepted return deadlines. It also covers reversed/equal symbol times,
|
||||
explicit preambles, newly infeasible short settings, long requested visits,
|
||||
invalid parameters and advisory-only switching overruns. CLI tests exercise
|
||||
warnings, both timing aliases, saved/temporary configuration, persistence
|
||||
and bounded replies. Native integration covers routing, retries and packet
|
||||
ownership alongside the timing model.
|
||||
|
||||
Verification completed on 2026-09-14 (local date):
|
||||
|
||||
- Exact commit snapshot: 24/24 host production tests passed, including primary
|
||||
CLI settings, shared timing, command dispatch, persistence and reply checks.
|
||||
- Native radio/routing/retry integration: 63/63 passed.
|
||||
- Existing HIL host regressions: 64/64 passed in the working checkout.
|
||||
- Both firmware builds passed from the isolated commit snapshot, without the
|
||||
unrelated local lab/Wi-Fi/extra modulation-cache edits: V4 repeater RAM
|
||||
125,336 bytes / flash 1,597,497 bytes; USB companion RAM 62,452 bytes /
|
||||
flash 828,257 bytes. Both passed runtime-RAM checks.
|
||||
- Staged whitespace and documentation-link checks passed. No radios were
|
||||
flashed for this function update.
|
||||
+98
-16
@@ -124,38 +124,119 @@ it automatically. Explicit values are used as entered, subject to the radio's
|
||||
limits and safe airtime arithmetic.
|
||||
|
||||
Automatic dual-profile preambles round **up to a multiple of eight**, with a
|
||||
32-symbol minimum. Each idle scan starts with **4.8 symbols on the slower
|
||||
profile**, then spends the remaining safe time on the faster profile. Slower
|
||||
32-symbol minimum. Each idle scan starts with **4.6 symbols on the slower
|
||||
profile**, then spends the remaining budgeted time on the faster profile,
|
||||
also with a **4.6-symbol floor**. Slower
|
||||
means a longer LoRa symbol (`2^SF / bandwidth`), regardless of profile number.
|
||||
The slower preamble sets the return deadline. The calculation allows two slow
|
||||
visits within that preamble, reserving 6 ms per switch and 4 ms of main-loop
|
||||
visits within that preamble, reserving 0.6 ms per switch and 0.3 ms of main-loop
|
||||
margin. Fast-channel transmit preambles include sixteen acquisition symbols.
|
||||
For a primary SF7 / 62.5 kHz profile:
|
||||
|
||||
| Secondary profile | Automatic secondary preamble | Tested explicit preamble | Primary preamble |
|
||||
| Secondary profile | Automatic secondary preamble | Previously tested explicit preamble | Primary preamble |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| SF9 / 500 kHz | 48 | 32 | 32 |
|
||||
| SF9 / 500 kHz | 32 | 32 | 32 |
|
||||
| SF8 / 500 kHz | 88 | 64 | 32 |
|
||||
| SF7 / 500 kHz | 120 | 80 | 32 |
|
||||
| SF7 / 500 kHz | 64 | 80 | 32 |
|
||||
|
||||
With preamble 32 on that slower profile, its visit is 9.831 ms and the faster
|
||||
visit is 6.937 ms, plus the actual switching time. Increasing the slow preamble
|
||||
With preamble 32 on that slower profile, its visit is 9.421 ms and the faster
|
||||
visit is 21.847 ms, plus the actual switching time. Increasing the slow preamble
|
||||
also increases the time available on the fast channel. If the symbols are equal
|
||||
in length, the primary profile goes first. Detected packets hold the current
|
||||
channel until reception finishes.
|
||||
|
||||
The SF8 / 500 kHz value also retains the measured 88-symbol floor from the
|
||||
production V4/XIAO tests, where 72 and 80 each missed a packet.
|
||||
The shorter explicit values come from the
|
||||
The explicit values come from the
|
||||
[production validation](radio_profiles_validation.md): the final fast-channel
|
||||
attempts each received 50/50 packets at 4.8 slow symbols. Automatic values retain
|
||||
the additional switching and loop-jitter margin.
|
||||
attempts each received 50/50 packets at 4.8 slow symbols. Automatic values use
|
||||
the switching and loop-jitter allowances below.
|
||||
Those explicit-preamble tests used the older 4.8-symbol policy; they do not
|
||||
validate the new 4.6-symbol slow dwell / 0.3 ms reserve. The
|
||||
[4.6/0.3 ms two-profile bench](radio_dwell_policy_validation.md#hardware-context) received 197/200
|
||||
at SF7/62.5 + SF8/500 with explicit 32-symbol preambles. The newer four-channel
|
||||
5.1/6.1/7.7 tests also had misses, so this is a timing policy, not a claim of zero packet loss.
|
||||
The automatic fast preamble covers the blind interval during the slow visit,
|
||||
both switches and the acquisition margin. These settings do not guarantee
|
||||
reception during overlapping packets or long pauses in the firmware loop.
|
||||
**Transmitters on each channel also need a long enough preamble.** Changing the
|
||||
receiver's setting does not lengthen packets sent by other nodes.
|
||||
|
||||
### Chirp calculator and warnings
|
||||
|
||||
`get radio2.timing` (alias `get radio.timing`) reports the active pair in
|
||||
`radio,radio2` order: dwell in chirps, recommended preambles in symbols, and
|
||||
the switching/loop allowances. For SF7/62.5 on `radio` and SF7/500 on `radio2`:
|
||||
|
||||
```text
|
||||
> chirps=4.60,85.34; need=32,64; switch=600us; loop=300us (estimate); WARN recommended preamble: radio2=64
|
||||
```
|
||||
|
||||
`WARN recommended preamble` identifies **each** profile whose recommendation
|
||||
exceeds the standard 32 symbols or its explicitly selected value. For example,
|
||||
with SF7/62.5 on the primary profile, `set radio2 910.5,500,7,5,rx,32` replies:
|
||||
|
||||
```text
|
||||
OK - radio2 rx; preamble=32; WARN recommended preamble: radio2=64; short override: radio2
|
||||
```
|
||||
|
||||
Successful `set radio ...` replies also include the recommended preamble for
|
||||
each affected profile, calculated with the requested settings. A `short override`
|
||||
note identifies an explicit value below the estimate; it is not silently
|
||||
rewritten. Warnings are also included in profile settings/getters, scan info,
|
||||
temporary settings and schedule acknowledgments. `off` disables the dual-profile
|
||||
warning. A timing readout does not change settings or transmit a packet.
|
||||
|
||||
The shared `RadioProfiles::calculateChirpTiming()` function accepts both tuples,
|
||||
optional visit times in microseconds, a per-switch allowance and loop margin.
|
||||
Using microseconds throughout:
|
||||
|
||||
```text
|
||||
T[i] = 2^SF[i] * 1000 / BW_kHz[i]
|
||||
slow = profile with the longer T (radio wins ties)
|
||||
L[slow] = max(requested_visit_us[slow], ceil(4.6 * T[slow]))
|
||||
L[fast] = max(requested_visit_us[fast], ceil(4.6 * T[fast]))
|
||||
O = 2 * switch_us + loop_margin_us
|
||||
C = L[radio] + L[radio2] + O
|
||||
|
||||
P[slow] = round_up_to_8(max(32, 2 * C / T[slow]))
|
||||
P[fast] = round_up_to_8(max(32, (L[slow] + O) / T[fast] + 16))
|
||||
```
|
||||
|
||||
The previous SF8/500 versus SF7/62.5 measured 88-symbol floor remains in force.
|
||||
Automatic selection uses the minimum visits to choose a preamble, then allocates
|
||||
the fast visit from half the slow preamble's duration. Diagnostics feed the
|
||||
actual allocated visits back into the same function, including longer visits
|
||||
caused by an explicit slow preamble. Too-short slow preambles that cannot fit
|
||||
both minimum visits remain rejected by the existing configuration validation.
|
||||
|
||||
The automatic scheduler uses these same role-specific minima and computes:
|
||||
|
||||
```text
|
||||
slow_dwell = ceil(4.6 * T[slow])
|
||||
fast_dwell = max(ceil(4.6 * T[fast]),
|
||||
floor(P_configured[slow] * T[slow] / 2 - slow_dwell - O))
|
||||
```
|
||||
|
||||
For the tested SF7/62.5 + SF8/500 pair with slow preamble 32, this yields
|
||||
9,421 us slow and 21,847 us fast (42.67 fast chirps). Swapping `radio` and
|
||||
`radio2` swaps the allocations automatically. The 0.3 ms reserve is not a sleep.
|
||||
|
||||
The calculator accepts board-specific allowances, but production scheduling
|
||||
uses the requested **600 us per switch plus 300 us per cycle**. This is a
|
||||
nominal fast-switch allowance, not a worst-case bound. Diagnostics use the
|
||||
larger of 600 us and the observed maximum
|
||||
switch time; an overrun increases the warning estimate without automatically
|
||||
changing wire preambles or saved configuration. Recent V4 tests peaked at
|
||||
836 us (827 us in the 4.6/0.3 ms run), and Indicator reached 8428 us:
|
||||
both can exceed the nominal allowance.
|
||||
The model preserves two slow-profile return opportunities and the existing
|
||||
16-symbol fast-profile acquisition allowance. These are conservative policies,
|
||||
not a fitted success curve, and neither packet overlap nor arbitrary application
|
||||
stalls can be made safe by a finite preamble recommendation.
|
||||
|
||||
See the [implementation and validation notes](radio_dwell_policy_validation.md).
|
||||
|
||||
## Schedule the second profile
|
||||
|
||||
Use UTC Unix timestamps (seconds):
|
||||
@@ -199,7 +280,7 @@ profile. Packets/retries bound to an expired or changed session are discarded.
|
||||
Dual mode suspends RX power saving and MCU idle sleep so receive visits can run
|
||||
promptly. The saved RX power-saving setting returns when profile 2 is off.
|
||||
The scan uses **normal receive**, following the
|
||||
[CAD/RX measurements](cad_scan_validation.md): 4.8 symbols on the slower
|
||||
[CAD/RX measurements](cad_scan_validation.md), with the updated 4.6-symbol dwell on the slower
|
||||
channel, followed by the remaining fast-channel visit. It does not use CAD for scanning.
|
||||
The separate CAD check before an initial transmission still follows `cad`.
|
||||
|
||||
@@ -212,8 +293,8 @@ This does not disable the TCXO supply or its initial startup delay, and it is
|
||||
not conditional on 500 kHz bandwidth. Keeping the oscillator on uses additional
|
||||
power during the short standby intervals.
|
||||
|
||||
The 6 ms switch budget is still a default scheduling allowance, not a
|
||||
forced delay, and has not been reduced for this change. The earlier standalone
|
||||
The requested 0.6 ms switch budget is a nominal scheduling allowance, not a
|
||||
forced settling delay or a measured worst-case bound. The earlier standalone
|
||||
[keep-warm scan experiment](mixed_scan_validation.md) averaged about 1.19 ms
|
||||
of overhead per hop (scan-cycle time minus both receive windows, divided by
|
||||
two). That experiment used a leaner receive path; it is not a measurement or
|
||||
@@ -247,8 +328,9 @@ Other variants do not opt in to faster SPI or the fast-RX state machine.
|
||||
See [production and USB validation](radio_profile_switch_validation.md#production-integration-and-usb-recovery-v8)
|
||||
for current measurements, lifecycle tests and limitations.
|
||||
The Indicator result also shows that the
|
||||
generic 6 ms allowance is not an upper bound for every board; its scheduling
|
||||
and preambles need board-specific qualification, not a smaller common budget.
|
||||
nominal 0.6 ms allowance is not an upper bound for every board; its scheduling
|
||||
and preambles need board-specific qualification. Measured overruns raise the
|
||||
recommended preambles shown by the CLI without rewriting configured values.
|
||||
|
||||
Single-channel noise-floor calibration and RSSI interference comparison are
|
||||
suspended while scanning. Retries use the radio's preamble/header activity
|
||||
|
||||
Reference in new issue
Block a user