Fix Yaesu FT-817/857/897 set-frequency encoder tens-of-Hz nibble - #614
Merged
Merged
Conversation
Yaesu2RigConstant.setOperationFreq packed the low nibble of the last BCD byte as `freq % 100` — the full 0-99 sub-100 Hz remainder crammed into a single 4-bit nibble. The rig's own decoder (Yaesu2Command.getFrequency) weights that nibble x10 as the tens-of-Hz digit, so the encoder and decoder were not inverses: setOperationFreq(14_074_050) round-tripped to 14_074_320 (+270 Hz), and endings whose remainder exceeded 15 produced a non-BCD nibble (>1 kHz off). On live TX this keys the rig on the wrong VFO for any dial that is not 100 Hz-aligned (10-Hz-resolution reads, custom bands per issue #470), pushing the FT8 signal off frequency. Root cause: the last nibble must be the tens-of-Hz digit `freq % 100 / 10` (the sub-10 Hz digit is below the rig's CAT resolution and is correctly dropped). This makes the encoder an exact inverse of the decoder for any 10 Hz-aligned VFO. PR #497 fixed the matching decoder and explicitly left this encoder quirk untouched; this completes the pair. Pure-JVM tests added/updated in Yaesu2RigConstantTest and Yaesu2CommandTest (tens-of-Hz encoding, full round-trip, sub-10 Hz drop); confirmed red against the old encoder, green with the fix. Full :app:testDebugUnitTest suite passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #614 +/- ##
=========================================
Coverage 36.62% 36.62%
Complexity 197 197
=========================================
Files 216 216
Lines 26885 26885
Branches 3294 3294
=========================================
Hits 9847 9847
Misses 16811 16811
Partials 227 227
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This pull request fixes Yaesu gen-2 (FT-817/857/897) CAT frequency encoding so that Yaesu2RigConstant.setOperationFreq correctly packs the tens-of-Hz digit into the low nibble of the last BCD byte, making the encoder consistent with the existing Yaesu2Command.getFrequency decoder (10 Hz CAT resolution).
Changes:
- Fix
setOperationFreqlast-nibble packing fromfreq % 100tofreq % 100 / 10(tens-of-Hz digit). - Add/adjust unit tests to cover non-100 Hz-aligned round-trips and document sub-10 Hz truncation.
- Refresh test documentation comments to match the corrected encoder/decoder relationship.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| ft8af/app/src/main/java/com/k1af/ft8af/rigs/Yaesu2RigConstant.java | Corrects the final BCD nibble packing to represent tens-of-Hz, aligning encoding with decoder expectations. |
| ft8af/app/src/test/java/com/k1af/ft8af/rigs/Yaesu2RigConstantTest.java | Adds a focused test asserting the tens-of-Hz digit is packed into the last nibble. |
| ft8af/app/src/test/java/com/k1af/ft8af/rigs/Yaesu2CommandTest.java | Updates the encoder↔decoder round-trip test to exercise sub-100 Hz digits and adds a test documenting sub-10 Hz loss. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
Yaesu2RigConstant.setOperationFreqpacks the low nibble of the last BCD frequency byte asfreq % 100— the entire 0–99 sub-100 Hz remainder crammed into a single 4-bit nibble:But the rig's own decoder,
Yaesu2Command.getFrequency, weights that same nibble ×10 as the tens-of-Hz digit:So the encoder is not the inverse of its own decoder. The 4-byte CAT block is 8 BCD nibbles with weights 1e8…1e1 (10 Hz LSB); the last nibble is the tens-of-Hz digit, i.e.
freq % 100 / 10, notfreq % 100.Impact
setOperationFreq(14_074_050)(14.074 MHz + 50 Hz) round-trips to 14_074_320 (+270 Hz).0x3A+), corrupting the frequency by >1 kHz.100 Hz-aligned dials (the common FT8 case,
freq % 100 == 0) were unaffected, which is why this slipped past.Fix
One-line change: pack the last nibble as the tens-of-Hz digit.
The sub-10 Hz digit is below the rig's CAT resolution and is correctly dropped (the decoder has no nibble for it either). The encoder is now an exact inverse of the decoder for any 10 Hz-aligned VFO.
PR #497 fixed the matching decoder and explicitly left this encoder quirk untouched; this completes the pair.
Testing
setOperationFreq_packsTensOfHzInLastNibble— asserts 14.074050 MHz encodes the 50 Hz component to low nibble0x05, not the raw remainder0x32.getFrequency_roundTripsSetOperationFreqEncodingto a non-100 Hz-aligned dial (14_074_350) so it exercises the tens-of-Hz nibble that previously desynced.getFrequency_dropsOnlySub10HzOnRoundTrip— documents that only the sub-10 Hz remainder is lost.:app:testDebugUnitTestsuite passes.Risk
Very low. Pure integer-arithmetic change in one BCD encoder, no protocol/DSP/threading surface. Behavior for the dominant 100 Hz-aligned case is byte-for-byte unchanged; only non-100 Hz-aligned dials — previously encoded wrong — change, and now round-trip correctly.