Repository navigation
IC-7600: stale IC-7200 leftovers in the .rig file (fix confirmed working) + three related memory save/recall bugs #108
Description
Sorry for another long one — this repo has clearly had a lot of careful work put into it, and I want to be upfront that some of this is source-reading rather than exhaustive hardware testing, so please treat all of it as "here's what we think we're seeing," not a demand. Happy to be told any part of this is wrong or already known.
Part 1: MemFormat / VFO A-B frequency tracking — fix already applied locally, confirmed working
While digging into why VFO A and VFO B always showed the same frequency, and separately why saved memory channels came back with blank names, we think we found that rigs/IC-7600.rig has a few fields that look copy-pasted from rigs/IC-7200.rig and never updated for the IC-7600's actual, richer command set:
MemFormat(line 25) was byte-for-byte identical toIC-7200.rig's — missing the memory-name and tone/TSQL fields the IC-7600 actually has (per the official IC-7600 CI-V manual, memory content command1A 00, page 177 in our copy).Commands\58(Memory Contents)'sMaxwas201, also copied from IC-7200, rather than matching this file's own correctly-setMemories=101.Commands\72/73(what would becomeSelected Freq/Unselected Freq, CI-V0x25) were present but disabled with a comment saying SET isn't implemented on this rig — we think the disabled version may have been shaped like IC-7610's single-command0x25(no explicit00/01sub-byte), rather than the explicit-subcommand formIC-7300.rigalready uses successfully. We can't be sure that's the actual reason SET was disabled, but it seemed worth mentioning.
We compared this against the official IC-7600 CI-V reference (main manual + the firmware V2.00 addendum) and against IC-7300.rig/IC-7610.rig's equivalent, working fields, and applied this locally:
MemFormat=%1.2b %3.1c %4.5f %9.1g %10.1h %11.1k %12.3n %15.3o %18.10z
Commands\58\Max=101 (was 201)
Commands\72\Type=Selected Freq
Commands\72\String=\x25\x00
Commands\72\GetCommand=true
Commands\72\SetCommand=false
Commands\73\Type=Unselected Freq
Commands\73\String=\x25\x01
Commands\73\GetCommand=true
Commands\73\SetCommand=false
Commands\76\Type=Selected Mode
Commands\76\String=\x26\x00
Commands\76\GetCommand=true
Commands\76\SetCommand=false
Commands\77\Type=Unselected Mode
Commands\77\String=\x26\x01
Commands\77\GetCommand=true
Commands\77\SetCommand=false
(plus matching Periodic entries for the new Selected/Unselected Freq+Mode commands, replacing the old plain Freq Get/Mode Get polls)
We've since tested this on a real IC-7600 and can confirm: VFO A and VFO B now track independently and correctly, and saving different frequencies to different memory channels now works (previously the write silently failed due to the truncated MemFormat payload). We deliberately left SetCommand=false on 0x25/0x26 since the manual says "send/read" but we don't have independent confirmation the SET direction is safe/correct on this rig — GetCommand is the part we're confident about.
We know real hardware CI-V behavior is something only you can fully verify against Icom's engineering notes, so please treat the above as a starting point rather than a finished patch.
Part 2: Three further bugs found while testing memory recall (not related to Part 1)
With Part 1's fix in place, memory save/recall became usable enough to notice these — all three seem to be pre-existing, general wfweb behavior, not specific to our local .rig changes. We think they compound each other, which made the symptoms hard to pin down at first ("sometimes it saves, sometimes it doesn't, no clear pattern").
2a. Entering MEM mode appears to mislabel the recalled memory's frequency as "VFO A"
As best we can tell from reading src/webserver.cpp and src/cachingqueue.cpp:
- Entering MEM mode (
selectVFO('MEM')in the UI) sends a bare CI-V08(no channel number) — which is genuine, expected radio behavior: the rig switches to whatever memory channel it last had selected internally and displays that frequency. getVfoCommand()picksfuncSelectedFreq(0x25 0x00) only whilerigState.vfoMode == vfoModeVfo. Once the rig reports it's in memory mode, it looks like the code falls back to a generic "current displayed frequency" query instead.receiveCache()'s generic frequency-reply handler then appears to write that value intovfoAFrequencyunconditionally, with no check onrigState.vfoMode— so the recalled memory channel's frequency gets sent to the browser labeled as VFO A's frequency.- We think this same path is also what
writeMemory()uses to source the frequency for a save — so if a save happens shortly after entering MEM mode, it may capture the memory-preview frequency rather than whatever was actually last dialed into VFO A, depending on poll timing.
This would explain "the frequency in memory channel 1 sometimes shows up in VFO A," and why save reliability seemed to depend on exact timing rather than anything about the channel itself.
2b. Command-queue dedup key doesn't appear to include the payload
queueItem::operator== in include/cachingqueue.h looks like it compares only (command, receiver, recurring) — not the actual parameter/value being sent. If that's right, addUnique() calls for funcMemoryContents (used by save, clear, and the per-channel memory-list scan) would all share the same identity regardless of which channel or value they carry, so a save/clear/scan-read landing close together in time could silently evict a still-pending command for a different channel before it's transmitted — with nothing surfaced to the log or the browser.
2c. The memory list's "next free channel" picker may read a cache that's mid-rebuild
refreshMemories() in resources/web/index.html appears to clear the browser's local memoryChannels object synchronously, then repopulate it gradually as the backend scans channels one at a time (roughly one every 500ms based on the timer we found). Since a save also triggers this same rescan on a 500ms delay, clicking "save" again (or delete) before the rescan has finished repopulating the list could mean nextFreeMemoryChannel() is working from an incomplete picture — which might explain the trouble reported when deleting all channels and then re-adding them.
We haven't attempted fixes for 2a/2b/2c ourselves — we wanted to describe what we found and let you decide the right approach, especially since 2b in particular sounds like it could have implications beyond just memory handling if addUnique() is used the same way elsewhere.
Thank you again for your patience with these reports — please let us know if it'd help to get more specific logs/traces from the real IC-7600 for any of this.
Activity
adecarolis commentedon Sep 20, 2026
Thanks for the careful report and the hardware test. Everything in it checked out, with one correction on the VFO part, and there is a test build ready:
Development Build (fix/ic7600-mainsub)
https://github.com/adecarolis/wfweb/releases/tag/dev-fix/ic7600-mainsub
For your Pi:
wfweb_0.9.0-dev-fix-ic7600-mainsub-debian13_arm64.deb. The package version is still 0.9.0, so install withsudo apt install --reinstall ./wfweb_0.9.0-dev-fix-ic7600-mainsub-debian13_arm64.deb. Please also remove any hand-editedIC-7600.rigfrom~/.local/share/wfweb/wfweb/rigs/first, otherwise it wins over the installed file. The log should then show the rig file loading as version 2.07.Part 1, MemFormat. Confirmed against the memory-contents layout in both the 2009 and 2015 manuals. Your line is byte for byte what the radio expects, and it was the IC-7200's line before, which is why names came back blank and writes were refused. Merged as you proposed, along with the Max fix.
Part 1, 0x25/0x26. Here the shape is slightly different. The IC-7600 has no VFO A/B at all: like the IC-7610 it has a MAIN and a SUB band. Command 07 only offers exchange, equalize, dual-watch and main/sub select (D0/D1), and the 25/26 sub-byte is the band (00 = MAIN, 01 = SUB), not "selected/unselected". Your layout labels correctly while MAIN is selected, but after selecting SUB the two readouts swap names. The build models the radio as Main/Sub, the same way wfweb already handles the IC-7610 and the way Hamlib treats the 7600. In the browser the VFO tile now reads MAIN/SUB, switches the band on the radio (it silently did nothing before, since the file had no VFO select at all), and each readout tracks its own band.
One consequence: 25/26 exist only from firmware 2.00, and this build polls them. A 7600 on older firmware will refuse them and lose frequency polling, so 2.00 is required from here on. You are on 2.00, so nothing to do.
2a, 2b, 2c. All three confirmed and fixed in this build. 2c is very likely what made saves feel random: every save triggered a full rescan that wiped the list, and a second save during those ten to twenty seconds proposed a channel the scan had not reached yet and overwrote it. The list now stays put during a rescan and "+ Save" waits for the first read of the group. 2b was real but narrow, since only memory commands are addressed by channel; those now bypass the dedup. 2a was cosmetic: in memory mode the channel frequency no longer lands in the VFO slots.
One question, since it can also produce a "wrong frequency saved": is CI-V Transceive ON in the radio's menu? Without it, a dial change on the front panel reaches wfweb only on the next poll, which can be several seconds later on this radio.
What I would like confirmed on the real radio: MAIN and SUB readouts independent and the tile switching bands, memory save with a name, recall, rename and clear, and two saves in a row landing on two different channels.
karlskontorp commentedon Sep 21, 2026
Thanks for the quick turnaround and the clear explanation of MAIN/SUB — that makes sense, and the correction on 0x25/0x26 was helpful.
Tested the dev build on a real IC-7600 (firmware 2.00, CI-V Transceive ON), Raspberry Pi 3, Debian 13 arm64. The installed IC-7600.rig is Version=2.07 and there is no user override, so everything below ran on the packaged file.
Works as described
One inconsistency when saving while SUB is selected
Setup: MAIN 14.200 MHz USB, SUB 7.100 MHz LSB.
So the stored frequency and mode come from MAIN, while the auto-generated name comes from the SUB readout that is on screen. As far as I can tell from reading
writeMemory, the frequency and mode are taken from the receiver-0 cache, and the name from the frequency currently shown. It took me a while to work out that the text after FIL1 on the radio is the channel name and not a second frequency. On this radio a memory channel only holds one frequency and mode (the MemFormat has a single frequency field), so I assume the intended behavior is that the save follows the selected band. If so, saving from SUB should store 7.100 LSB. If not, the auto-name should at least be built from the values that are actually written.Small suggestions, all cosmetic
Feature request: a way to reach 60 m (and the GENE key)
Would it be possible to add a key for 60 m to the band picker? I know the 60 m allocations differ between countries and regions, but WRC-15 gave the amateur service secondary status in 5351.5–5366.5 kHz, and many of us can now use it.
I saw in the
BAND_KEYScomment that 60 m is left out because Icom panels have no dedicated key for it, and that it is reached through F-INP instead. That is true for a 60 m key, but the radio does have a GENE key, and as far as I can tell from using it, it behaves exactly like the other band keys, including the band stacking register. The only difference is that GENE covers all of HF plus 6 m instead of one amateur band. If I set GENE to 60 m, it acts as if there had been a 60 m key. Because it has three stack registers, it can also hold three different frequencies, depending on what I entered the last three times I used it.So one option would be a GENE key in the web band picker, working like the other band keys, which would cover 60 m and anything else outside the amateur bands. Another would be a dedicated 60 m key that lands on 5351.5 kHz the first time. The IC-7600 rig file already has a band entry around 5.25–5.45 MHz (
Bands\11), so the radio knows that range. Either would be very welcome, though I understand if you would rather keep the picker limited to the amateur bands. Not urgent.Minor note, not a bug
I tried to confirm the rig file version from the journal, but "Found Rig ... version 2.07" is a qDebug line, so it only appears with debug logging on. I checked the file directly instead. You may want it at info level if you ask users to confirm the version from the log.
Thanks again for all the work on this.
fix(web): save a memory from the band you are on, name the loaded rig…
fix(web): name the bands MAIN/SUB, stop showing a frequency as a chan…
adecarolis commentedon Sep 22, 2026
Thank you for the thorough hardware test, and for pinning down the save inconsistency so precisely. Your reading of
writeMemorywas right, and the GENE observation was right too.A new build is on the same release, rebuilt from the branch a few minutes ago:
Development Build (fix/ic7600-mainsub)
https://github.com/adecarolis/wfweb/releases/tag/dev-fix/ic7600-mainsub
Same file for your Pi,
wfweb_0.9.0-dev-fix-ic7600-mainsub-debian13_arm64.deb, samesudo apt install --reinstall ./<file>since the package version does not change.Saving while SUB is selected. Fixed, and it was exactly as you described. The write asked the cache for receiver 0, which on a Main/Sub rig is always MAIN, while everything else picks the receiver from the selected band. That is why recall behaved and save did not. It now takes the receiver from the band you are on, for the repeater tone, shift and offset as well as frequency and mode. The name needed no separate fix: it was only ever disagreeing because the stored values were wrong, so correcting the write makes both agree. Worth noting this was not new, and it affects the IC-7610 the same way. It only became reachable on the IC-7600 once the VFO tile started switching bands instead of silently doing nothing.
The MAIN/SUB labels. Done. The memory panel's selector now reads MAIN and SUB on this radio, matching the VFO tile and your front panel. Rigs that really do have VFO A and B still say so.
The name that looks like a frequency. Done, and your diagnosis of why it reads badly was the useful part. The save still writes that label to the radio so its own memory list is not blank, but the browser now recognises a label that merely restates the frequency below it and shows the row in its frequency-only form instead. A name you type is unaffected and still sits above the frequency. The rename field also has a "channel name" placeholder now, so it is clear what you are editing.
The log level. Done, though not where you might expect. The line you found is part of the scan over the rig directory and fires once per file, so raising it would add about thirty lines to every startup. The version now rides on the line that names the rig actually loaded, which was already at info level. You should see
Loading Rig: IC-7600 version 2.07 from ...without debug logging.60 m and GENE. I checked the rig file against what you described and it holds up: 60 m has no band stacking register, which is why it has no key, while GENE has one and covers 10 kHz to 60 MHz. I have split that off as its own issue rather than folding it in here, since it is a design question about what belongs in an amateur-band picker rather than a bug.
One thing I did not change, in case you notice it: the status the browser receives still reports the MAIN frequency while SUB is selected. The main display does not use that field, which is why your readouts looked right, so it is cosmetic rather than something you would see. I would rather fix it separately than widen this build.
If you have time, the things worth retesting are: saving while SUB is selected, which should now store the SUB frequency, mode and a matching name; the MAIN/SUB buttons; that channel rows no longer show a frequency where the name goes; and the version line in the log. If those all look right I will merge this.
karlskontorp commentedon Sep 23, 2026
Thanks for the detailed explanation and the quick turnaround — retested all four points on the real IC-7600.
--debug. Works.All four look good from here. Thanks again for fixing this so quickly.
adecarolis commentedon Sep 25, 2026
Thanks for going back to the radio and checking all four. That is now merged, and it will ship in the next release.
For the record, what this issue produced:
IC-7600.rigno longer carries IC-7200 leftovers: yourMemFormat, the memory count, and the radio modelled as the MAIN/SUB rig it is, with 0x25/0x26 on firmware 2.00.On the placeholder: you are right that it is ordinary placeholder behaviour, and it was what I intended. The field only ever holds the channel name, so once there is text in it there is nothing to disambiguate. If it turns out to be confusing in practice, say so and I will look at a persistent label.
Your 60 m request is now #116, with the GENE stacking-register detail you found. It holds up beyond the IC-7600, though not universally: the IC-7610 declares no stacking register for GENE, so any key would have to be gated on each rig's own band table. What remains is the design question of whether a general-coverage key belongs in an otherwise amateur-band picker.
Closing this one. Thank you for the unusually careful reports throughout, and for testing each build on real hardware. That is what made these fixable.
Merge branch 'fix/ic7600-mainsub' into dev