Add MEDIUM_TURBO modem preset - #10988
Conversation
MEDIUM_TURBO (500 kHz, SF9, CR 4/5) already existed in the protobuf enum but was never wired into firmware, so selecting it silently fell through to the LONG_FAST default and rendered an "Invalid" display name. Add its bw/sf/cr mapping (modemPresetToParams), display name (MediumTurbo/MedT), PRESETS_STD membership (standard regions only — 500 kHz does not fit EU868's 250 kHz band, so it stays out of PRESETS_EU_868 and is rejected/clamped there), and the MEDIUM SNR-grading bucket. Includes positive coverage in test_radio, EU868-reject + US-accept coverage in test_admin_radio and test_mesh_beacon, the STD preset count 9->10, an extended fuzz range, and the client-spec doc.
⚡ Try this PR in the Web FlasherWarning This is an automated, unreviewed CI test build. Back up your device configuration Supported boards built by this PR (27)
Build artifacts expire on 2026-08-10. Updated for |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe standard LoRa preset set now includes ChangesMEDIUM_TURBO preset support
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
test/test_mesh_beacon/test_main.cpp (1)
254-257: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCondense the new comments to the repository’s C++ style.
Each added Doxygen block spans four lines. Keep the rationale to one concise line; the test names and assertions already explain the behavior. As per coding guidelines, C++ comments should be at most one or two lines and should not restate obvious code.
Proposed comment simplification
-/** - * Verify MEDIUM_TURBO is also cleared for EU_868. Like SHORT_TURBO/LONG_TURBO it is a 500 kHz preset - * that does not fit EU_868's 250 kHz band, so it must not survive admin validation there. - */ +// MEDIUM_TURBO must be cleared for EU_868 because its 500 kHz bandwidth is unsupported. ... -/** - * Verify MEDIUM_TURBO passes validation for US (PROFILE_STD allows the full turbo family). - * The same 500 kHz preset that is illegal in EU_868 must be preserved in permissive regions. - */ +// MEDIUM_TURBO is preserved for US because PROFILE_STD allows the full turbo family.Also applies to: 271-274
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/test_mesh_beacon/test_main.cpp` around lines 254 - 257, Condense the new Doxygen comments near the MEDIUM_TURBO and corresponding test cases to one concise line each, retaining only the non-obvious rationale. Keep the existing test names and assertions unchanged, and follow the repository’s one- or two-line C++ comment style.Source: Coding guidelines
test/test_radio/test_main.cpp (1)
198-210: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCover the
wideLorabranch for MEDIUM_TURBO.This test exercises only US/non-wide behavior, so it cannot catch a regression in the required 1625 kHz LORA_24 mapping. Add a second case using
RegionCode_LORA_24and assert1625.0f.Possible extension
TEST_ASSERT_FLOAT_WITHIN(0.01f, 500.0f, testRadio->getBw()); + + config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_LORA_24; + initRegion(); + testRadio->reconfigure(); + TEST_ASSERT_FLOAT_WITHIN(0.01f, 1625.0f, testRadio->getBw());🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/test_radio/test_main.cpp` around lines 198 - 210, Add a second scenario to test_applyModemConfig_mediumTurbo using RegionCode_LORA_24, reconfigure the radio, and assert that getBw() returns 1625.0f while preserving the existing MEDIUM_TURBO parameter assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@test/test_mesh_beacon/test_main.cpp`:
- Around line 262-269: Update the test around handleSetModuleConfig to assert
moduleConfig.has_mesh_beacon is true before asserting
mesh_beacon.has_broadcast_on_preset is false, confirming the sanitized
configuration was persisted rather than dropped. Match the assertion pattern
used by the existing SHORT_TURBO test.
---
Nitpick comments:
In `@test/test_mesh_beacon/test_main.cpp`:
- Around line 254-257: Condense the new Doxygen comments near the MEDIUM_TURBO
and corresponding test cases to one concise line each, retaining only the
non-obvious rationale. Keep the existing test names and assertions unchanged,
and follow the repository’s one- or two-line C++ comment style.
In `@test/test_radio/test_main.cpp`:
- Around line 198-210: Add a second scenario to
test_applyModemConfig_mediumTurbo using RegionCode_LORA_24, reconfigure the
radio, and assert that getBw() returns 1625.0f while preserving the existing
MEDIUM_TURBO parameter assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 0b2db170-7e71-46a3-9698-d5d1b7f25037
⛔ Files ignored due to path filters (1)
src/mesh/generated/meshtastic/config.pb.his excluded by!**/generated/**,!src/mesh/generated/**
📒 Files selected for processing (12)
.gitignoredocs/lora_region_preset_compatibility_client_spec.mdprotobufssrc/DisplayFormatters.cppsrc/graphics/draw/UIRenderer.cppsrc/mesh/MeshRadio.hsrc/mesh/RadioInterface.cppsrc/modules/CannedMessageModule.cpptest/test_admin_radio/test_main.cpptest/test_fuzz_packets/test_main.cpptest/test_mesh_beacon/test_main.cpptest/test_radio/test_main.cpp
There was a problem hiding this comment.
Pull request overview
This PR wires the MEDIUM_TURBO LoRa modem preset into the firmware so it no longer falls back to LONG_FAST, and ensures it is surfaced consistently across parameter mapping, preset availability per region, UI display names, and validation/tests.
Changes:
- Add
MEDIUM_TURBOmodem-preset → parameter mapping (500 kHz / SF9 / CR 4/5; wideLoRa uses 1625 kHz). - Expose the preset in standard-region preset lists and UI/display/SNR-bucket logic.
- Extend unit tests and fuzz coverage to include the new enum value and region allow/deny behavior.
Reviewed changes
Copilot reviewed 11 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/test_radio/test_main.cpp | Adds unit coverage for applying MEDIUM_TURBO params and clamping it out for EU868. |
| test/test_mesh_beacon/test_main.cpp | Extends admin validation tests for beacon preset handling of MEDIUM_TURBO (EU868 cleared, US accepted). |
| test/test_fuzz_packets/test_main.cpp | Extends fuzz range to include the new modem preset enum value. |
| test/test_admin_radio/test_main.cpp | Updates region/preset validation tests and expected PROFILE_STD preset count. |
| src/modules/CannedMessageModule.cpp | Includes MEDIUM_TURBO in the “MEDIUM” SNR grading bucket. |
| src/mesh/RadioInterface.cpp | Adds MEDIUM_TURBO to PRESETS_STD availability list. |
| src/mesh/MeshRadio.h | Implements MEDIUM_TURBO mapping in modemPresetToParams(). |
| src/mesh/generated/meshtastic/config.pb.h | Updates generated enum to include MEDIUM_TURBO=16 and adjusts MAX/ARRAYSIZE. |
| src/graphics/draw/UIRenderer.cpp | Includes MEDIUM_TURBO in the “MEDIUM” SNR grading bucket for UI. |
| src/DisplayFormatters.cpp | Adds display names for MEDIUM_TURBO (MedT / MediumTurbo). |
| docs/lora_region_preset_compatibility_client_spec.md | Updates client spec docs for the standard preset group (9 → 10 presets). |
| .gitignore | Ignores .pio-docker build artifacts. |
- test_mesh_beacon: assert has_mesh_beacon before checking the invalid preset was cleared, so the EU868-cleared test can't pass on a dropped message (matches the existing SHORT_TURBO test). - test_fuzz_packets: draw modem presets from _ModemPreset_ARRAYSIZE instead of a hard-coded 17 so the fuzz range tracks future enum additions automatically.
|
Hi, is it ensured somehow that the 500khz TURBO presets are not selectable on EU_868? also, here on page 22, section P, band number 54 https://www.etsi.org/deliver/etsi_en/300200_300299/30022002/03.02.01_60/en_30022002v030201p.pdf Frequency slot calculator also shows no frequency slot available. On the Android App, I can select the TURBO presets from the dropdown list when selecting region EU_868. Is it technically possible to remove some frequency presets based on the region? |
* Protobufs * Wire up MEDIUM_TURBO modem preset MEDIUM_TURBO (500 kHz, SF9, CR 4/5) already existed in the protobuf enum but was never wired into firmware, so selecting it silently fell through to the LONG_FAST default and rendered an "Invalid" display name. Add its bw/sf/cr mapping (modemPresetToParams), display name (MediumTurbo/MedT), PRESETS_STD membership (standard regions only — 500 kHz does not fit EU868's 250 kHz band, so it stays out of PRESETS_EU_868 and is rejected/clamped there), and the MEDIUM SNR-grading bucket. Includes positive coverage in test_radio, EU868-reject + US-accept coverage in test_admin_radio and test_mesh_beacon, the STD preset count 9->10, an extended fuzz range, and the client-spec doc. * Address review feedback on MEDIUM_TURBO tests - test_mesh_beacon: assert has_mesh_beacon before checking the invalid preset was cleared, so the EU868-cleared test can't pass on a dropped message (matches the existing SHORT_TURBO test). - test_fuzz_packets: draw modem presets from _ModemPreset_ARRAYSIZE instead of a hard-coded 17 so the fuzz range tracks future enum additions automatically.
Add the MEDIUM_TURBO modem preset
MEDIUM_TURBO(enum value 16) already existed in the protobufs but was never wired into firmware — selecting it silently fell through to theLONG_FASTdefault and rendered anInvaliddisplay name (which also feeds channel-frequency-slot hashing). This PR wires it up.Per the proto definition, it "performs similarly to MEDIUM_FAST, but with 500kHz bandwidth. It is not legal to use in all regions due to this wider bandwidth."
Spec
500 kHz bandwidth (1625 kHz on 2.4 GHz
wideLoraregions), SF9, CR 4/5 — i.e. MEDIUM_FAST's spreading factor and coding rate at double the bandwidth.Where it lands among the sub-GHz presets by on-air throughput:
3rd-fastest preset — ~2× the throughput of Medium Fast (same SF9, double bandwidth), true medium range.
500 kHz "wide" handling
It's added to
PRESETS_STD(US and other wide-capable regions) but deliberately not toPRESETS_EU_868— EU868's band is only 250 kHz wide. The two existing backstops enforce this automatically: preset-list membership (supportsPreset) and the region-span physical-fit check. Verified: it resolves to 500/SF9/CR4:5 in US and is rejected + clamped toLONG_FASTin EU_868 and UNSET.Changes
modemPresetToParams()inMeshRadio.hMediumTurbo/MedTinDisplayFormatters.cppPRESETS_STD(turbo cluster) inRadioInterface.cppUIRenderer.cppandCannedMessageModule.cpptest_radio; EU868-reject + US-accept intest_admin_radioandtest_mesh_beacon; preset count 9→10; fuzz range extended to include the new valuelora_region_preset_compatibility_client_spec.mdThe InkHUD preset menu picks up the new preset automatically via its dynamic region-list path (same as
LONG_TURBO), so no InkHUD change is needed.Testing
Native test suite green: 578/578 test cases, 0 failures, 0 ignored (all 30 suites, via the Docker native-test path).
Summary by CodeRabbit
Medium TurboLoRa modem preset, including parameter mapping.MEDIUM_TURBO.MEDIUM_TURBOis accepted in US configurations and rejected/cleared in EU 868 configurations.MEDIUM_TURBO.