From bd2edf66240ec23937ebfc3af74d180eea516563 Mon Sep 17 00:00:00 2001 From: rouggy Date: Sat, 29 Aug 2026 15:36:55 +0200 Subject: [PATCH] fix(icom): verify the data flag after a mode set, and correct it with 0x26 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IC-7760 acknowledges the 1A 06 data-mode command and stays in USB-D anyway, which left the operator unable to get back to plain USB from the console at all. After every mode set the flag is read back; on a mismatch it is said again with 0x26 — mode, data flag and filter in one frame, the form the newer rigs actually honour. Only on a mismatch, so rigs that predate 0x26 never see the command. --- changelog.json | 6 ++++-- internal/cat/civ/civ.go | 1 + internal/cat/icomserial.go | 12 ++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/changelog.json b/changelog.json index b9c527e..66beaaf 100644 --- a/changelog.json +++ b/changelog.json @@ -7,14 +7,16 @@ "Elecraft console: an SWR spike (the K3’s own blip at the end of an FT8 frame) no longer fades over twelve seconds — the peak shows briefly, then the meter returns straight to the live reading.", "Icom: the IC-7760 joins the model list (CI-V address B2h).", "Icom console: the IC-7760 gets its real attenuator steps — 6/12/18 dB.", - "Icom network audio: the RX stream is decoded correctly — mono is requested and the payload offset was confirmed on a real IC-7760, curing the garbled, clicking audio." + "Icom network audio: the RX stream is decoded correctly — mono is requested and the payload offset was confirmed on a real IC-7760, curing the garbled, clicking audio.", + "Icom: switching back from a data mode (USB-D1) to plain USB now sticks — if the rig ignores the data-flag command, it is repeated with the modern one-frame form (0x26). Seen on the IC-7760." ], "fr": [ "Console Elecraft : le S-mètre est calibré sur un vrai K3 — S9 et les +dB correspondent désormais à l’affichage de la radio (il lisait environ deux points S trop bas).", "Console Elecraft : un pic de ROS (le sursaut du K3 en fin de trame FT8) ne s’estompe plus pendant douze secondes — le pic s’affiche brièvement, puis le ros-mètre revient directement à la valeur réelle.", "Icom : l’IC-7760 rejoint la liste des modèles (adresse CI-V B2h).", "Console Icom : l’IC-7760 reçoit ses vrais crans d’atténuateur — 6/12/18 dB.", - "Audio réseau Icom : le flux RX est décodé correctement — le mono est demandé et l’offset du payload a été confirmé sur un vrai IC-7760, ce qui guérit le son inaudible et les clics." + "Audio réseau Icom : le flux RX est décodé correctement — le mono est demandé et l’offset du payload a été confirmé sur un vrai IC-7760, ce qui guérit le son inaudible et les clics.", + "Icom : revenir d’un mode data (USB-D1) au USB simple tient désormais — si la radio ignore la commande du drapeau data, elle est répétée sous la forme moderne en une trame (0x26). Constaté sur l’IC-7760." ] }, { diff --git a/internal/cat/civ/civ.go b/internal/cat/civ/civ.go index 3400aef..2f37504 100644 --- a/internal/cat/civ/civ.go +++ b/internal/cat/civ/civ.go @@ -36,6 +36,7 @@ const ( CmdVfoFreq = 0x25 // read a specific VFO's freq (sub 0x00 selected, 0x01 unselected) CmdPTT = 0x1C // sub 0x00 = PTT CmdExtra = 0x1A // sub 0x06 = data mode on modern Icoms + CmdModeDataFil = 0x26 // sub 0x00 = selected VFO: mode + data flag + filter in one frame CmdReadID = 0x19 // sub 0x00 = rig's own CI-V address (identifies model) CmdPower = 0x18 // power on/off (sub 0x01 = on, 0x00 = off; on needs an FE wake preamble) diff --git a/internal/cat/icomserial.go b/internal/cat/icomserial.go index 3a37c1c..fe2eae4 100644 --- a/internal/cat/icomserial.go +++ b/internal/cat/icomserial.go @@ -559,6 +559,18 @@ func (b *IcomSerial) SetMode(mode string) error { } // Filter 0x01 (FIL1) is the conventional default for the data-mode set. _ = b.execIdempotent("set data mode", civ.CmdExtra, civ.SubDataMode, dataByte, 0x01) + // Trust, then verify: the IC-7760 acknowledges 1A 06 and stays in USB-D + // anyway, which left an operator unable to get back to plain USB at all. + // When the readback disagrees, say it again with 0x26 — mode, data flag and + // filter in one frame, the command the newer rigs actually honour. Only on + // a mismatch, so rigs that predate 0x26 never see it. + if got := b.readDataMode(); got != data { + if err := b.execIdempotent("set mode+data (0x26)", civ.CmdModeDataFil, 0x00, code, dataByte, 0x01); err != nil { + applog.Printf("icom: data flag stuck at %v after mode %s, and 0x26 failed too: %v", got, mode, err) + } else { + applog.Printf("icom: data flag stuck after 1A06, corrected via 0x26 (mode %s)", mode) + } + } return nil }