fix(icom): the SUB dial is always shown, and split aligns the TX mode
The unselected VFO was read only when split was on, so a dual-receiver rig's second dial sat blank on the console. It is now read on the same slow beat regardless. And engaging split copies the main's mode (and data flag) onto the TX VFO with 0x26 01 — a split whose TX VFO still speaks yesterday's mode transmits FM into a CW pileup; rigs that predate 0x26 NAK it harmlessly.
This commit is contained in:
+4
-2
@@ -25,7 +25,8 @@
|
|||||||
"Icom network audio: listening is now a remembered choice — Stop listening keeps the speakers off across reconnects and restarts, while the stream stays open for the QSO recorder and the voice keyer.",
|
"Icom network audio: listening is now a remembered choice — Stop listening keeps the speakers off across reconnects and restarts, while the stream stays open for the QSO recorder and the voice keyer.",
|
||||||
"Icom console: a speaker button beside ON/OFF toggles listening to the network RX audio right from the console — no more trip through Settings → Audio; recordings and the voice keyer keep working either way, and the choice is remembered.",
|
"Icom console: a speaker button beside ON/OFF toggles listening to the network RX audio right from the console — no more trip through Settings → Audio; recordings and the voice keyer keep working either way, and the choice is remembered.",
|
||||||
"CAT settings: a “Play it through the speakers” checkbox sits under the Icom RX-audio option — the same remembered switch as the console’s speaker button, applied immediately.",
|
"CAT settings: a “Play it through the speakers” checkbox sits under the Icom RX-audio option — the same remembered switch as the console’s speaker button, applied immediately.",
|
||||||
"Icom network audio: “Talk to radio” now works over the LAN too — live microphone straight to the rig, PTT included. With RX audio and a headset, OpsLog is a complete remote station: hear, talk, key CW and log over one network link."
|
"Icom network audio: “Talk to radio” now works over the LAN too — live microphone straight to the rig, PTT included. With RX audio and a headset, OpsLog is a complete remote station: hear, talk, key CW and log over one network link.",
|
||||||
|
"Icom console: the SUB display shows the sub receiver’s frequency at all times (it was blank until split), and engaging split copies the mode to the TX VFO so it matches the main."
|
||||||
],
|
],
|
||||||
"fr": [
|
"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 : 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).",
|
||||||
@@ -50,7 +51,8 @@
|
|||||||
"Audio réseau Icom : l’écoute est désormais un choix mémorisé — Stop listening garde les enceintes coupées à travers reconnexions et redémarrages, tandis que le flux reste ouvert pour l’enregistreur de QSO et le voice keyer.",
|
"Audio réseau Icom : l’écoute est désormais un choix mémorisé — Stop listening garde les enceintes coupées à travers reconnexions et redémarrages, tandis que le flux reste ouvert pour l’enregistreur de QSO et le voice keyer.",
|
||||||
"Console Icom : un bouton haut-parleur à côté de ON/OFF bascule l’écoute du RX audio réseau depuis la console — fini l’aller-retour dans Réglages → Audio ; enregistrements et voice keyer continuent de fonctionner, et le choix est mémorisé.",
|
"Console Icom : un bouton haut-parleur à côté de ON/OFF bascule l’écoute du RX audio réseau depuis la console — fini l’aller-retour dans Réglages → Audio ; enregistrements et voice keyer continuent de fonctionner, et le choix est mémorisé.",
|
||||||
"Réglages CAT : une case « Écouter dans les enceintes » sous l’option RX audio Icom — le même interrupteur mémorisé que le bouton haut-parleur de la console, appliqué immédiatement.",
|
"Réglages CAT : une case « Écouter dans les enceintes » sous l’option RX audio Icom — le même interrupteur mémorisé que le bouton haut-parleur de la console, appliqué immédiatement.",
|
||||||
"Audio réseau Icom : « Talk to radio » fonctionne aussi par le LAN — micro en direct vers la radio, PTT compris. Avec le RX audio et un casque, OpsLog devient une station remote complète : écouter, parler, manipuler la CW et loguer sur un seul lien réseau."
|
"Audio réseau Icom : « Talk to radio » fonctionne aussi par le LAN — micro en direct vers la radio, PTT compris. Avec le RX audio et un casque, OpsLog devient une station remote complète : écouter, parler, manipuler la CW et loguer sur un seul lien réseau.",
|
||||||
|
"Console Icom : l’affichage SUB montre la fréquence du sub receiver en permanence (il restait vide hors split), et activer le split copie le mode sur le VFO TX pour qu’il suive le main."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { ShiftRow } from '@/components/ShiftRow';
|
|||||||
|
|
||||||
type IcomState = {
|
type IcomState = {
|
||||||
available: boolean; model?: string; mode?: string;
|
available: boolean; model?: string; mode?: string;
|
||||||
transmitting: boolean; split: boolean;
|
transmitting: boolean; split: boolean; sub_hz?: number;
|
||||||
s_meter: number; power_meter: number; swr_meter: number;
|
s_meter: number; power_meter: number; swr_meter: number;
|
||||||
rf_power: number; mic_gain: number;
|
rf_power: number; mic_gain: number;
|
||||||
af_gain: number; rf_gain: number;
|
af_gain: number; rf_gain: number;
|
||||||
@@ -692,7 +692,10 @@ export function IcomPanel({ onReportRST, isNetwork = false }: { onReportRST?: (r
|
|||||||
// other is TX (freq_hz); otherwise there's a single VFO (freq_hz).
|
// other is TX (freq_hz); otherwise there's a single VFO (freq_hz).
|
||||||
const split = !!cat?.split;
|
const split = !!cat?.split;
|
||||||
const mainHz: number = split ? (cat?.freq_rx_hz || 0) : (cat?.freq_hz || 0);
|
const mainHz: number = split ? (cat?.freq_rx_hz || 0) : (cat?.freq_hz || 0);
|
||||||
const subHz: number = split ? (cat?.freq_hz || 0) : 0;
|
// The sub receiver's dial is worth seeing whether or not split is on —
|
||||||
|
// in split the CAT state's TX freq is the authority, otherwise the panel's
|
||||||
|
// own sub_hz read.
|
||||||
|
const subHz: number = split ? (cat?.freq_hz || 0) : (st.sub_hz || 0);
|
||||||
const curMode: string = cat?.mode || st.mode || '';
|
const curMode: string = cat?.mode || st.mode || '';
|
||||||
// Mode-dependent controls: VOX / speech-comp / mic are voice-only (hidden on
|
// Mode-dependent controls: VOX / speech-comp / mic are voice-only (hidden on
|
||||||
// CW and data); APF (audio peak filter) is CW-only. Fold USB/LSB into phone.
|
// CW and data); APF (audio peak filter) is CW-only. Fold USB/LSB into phone.
|
||||||
|
|||||||
@@ -983,6 +983,7 @@ export namespace cat {
|
|||||||
mode?: string;
|
mode?: string;
|
||||||
transmitting: boolean;
|
transmitting: boolean;
|
||||||
split: boolean;
|
split: boolean;
|
||||||
|
sub_hz: number;
|
||||||
s_meter: number;
|
s_meter: number;
|
||||||
power_meter: number;
|
power_meter: number;
|
||||||
swr_meter: number;
|
swr_meter: number;
|
||||||
@@ -1030,6 +1031,7 @@ export namespace cat {
|
|||||||
this.mode = source["mode"];
|
this.mode = source["mode"];
|
||||||
this.transmitting = source["transmitting"];
|
this.transmitting = source["transmitting"];
|
||||||
this.split = source["split"];
|
this.split = source["split"];
|
||||||
|
this.sub_hz = source["sub_hz"];
|
||||||
this.s_meter = source["s_meter"];
|
this.s_meter = source["s_meter"];
|
||||||
this.power_meter = source["power_meter"];
|
this.power_meter = source["power_meter"];
|
||||||
this.swr_meter = source["swr_meter"];
|
this.swr_meter = source["swr_meter"];
|
||||||
|
|||||||
+7
-3
@@ -572,9 +572,13 @@ type IcomTXState struct {
|
|||||||
// Transmit + live status (polled).
|
// Transmit + live status (polled).
|
||||||
Transmitting bool `json:"transmitting"`
|
Transmitting bool `json:"transmitting"`
|
||||||
Split bool `json:"split"`
|
Split bool `json:"split"`
|
||||||
SMeter int `json:"s_meter"` // 0-100 (raw 0-255; S9≈120)
|
// SubHz is the unselected VFO / sub receiver's frequency — shown on the
|
||||||
PowerMeter int `json:"power_meter"` // 0-100 (TX Po)
|
// console's SUB display whether or not split is on: a dual-receiver rig
|
||||||
SWRMeter int `json:"swr_meter"` // 0-100 (TX SWR)
|
// (IC-7610/7760) has a second dial worth seeing at all times.
|
||||||
|
SubHz int64 `json:"sub_hz"`
|
||||||
|
SMeter int `json:"s_meter"` // 0-100 (raw 0-255; S9≈120)
|
||||||
|
PowerMeter int `json:"power_meter"` // 0-100 (TX Po)
|
||||||
|
SWRMeter int `json:"swr_meter"` // 0-100 (TX SWR)
|
||||||
// RIT / ΔTX (XIT).
|
// RIT / ΔTX (XIT).
|
||||||
RITHz int `json:"rit_hz"` // RIT/XIT offset, signed Hz
|
RITHz int `json:"rit_hz"` // RIT/XIT offset, signed Hz
|
||||||
RITOn bool `json:"rit_on"`
|
RITOn bool `json:"rit_on"`
|
||||||
|
|||||||
@@ -414,8 +414,13 @@ func (b *IcomSerial) ReadState() (RigState, error) {
|
|||||||
// all, for the user's Set* commands.
|
// all, for the user's Set* commands.
|
||||||
if b.pollN%4 == 1 {
|
if b.pollN%4 == 1 {
|
||||||
b.splitOn, b.splitTXFreq = false, 0
|
b.splitOn, b.splitTXFreq = false, 0
|
||||||
if on, ok := b.readSplit(); ok && on {
|
on, okSplit := b.readSplit()
|
||||||
if txHz, ok2 := b.readTXFreq(); ok2 && txHz > 0 {
|
// The unselected VFO is read split or NOT: on a dual-receiver rig it is
|
||||||
|
// the sub receiver's dial, and the console showed it blank until split
|
||||||
|
// was engaged.
|
||||||
|
if txHz, ok2 := b.readTXFreq(); ok2 && txHz > 0 {
|
||||||
|
b.setCache(func(st *IcomTXState) { st.SubHz = txHz })
|
||||||
|
if okSplit && on {
|
||||||
b.splitOn, b.splitTXFreq = true, txHz
|
b.splitOn, b.splitTXFreq = true, txHz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1872,6 +1877,17 @@ func (b *IcomSerial) SetIcomSplit(on bool) error {
|
|||||||
}
|
}
|
||||||
_ = b.exec(append([]byte{civ.CmdVfoFreq, civ.SubVfoUnselected}, civ.FreqToBCD(rx+offset)...)...)
|
_ = b.exec(append([]byte{civ.CmdVfoFreq, civ.SubVfoUnselected}, civ.FreqToBCD(rx+offset)...)...)
|
||||||
}
|
}
|
||||||
|
// And the MODE crosses with it: a split where the TX VFO is still on
|
||||||
|
// yesterday's mode transmits FM into a CW pileup. 0x26 0x01 sets the
|
||||||
|
// unselected VFO's mode + data flag in one frame; rigs that predate
|
||||||
|
// 0x26 NAK it harmlessly and behave as they always did.
|
||||||
|
if b.curModeByte != 0 {
|
||||||
|
dataByte := byte(0)
|
||||||
|
if got := b.readDataMode(); got {
|
||||||
|
dataByte = 1
|
||||||
|
}
|
||||||
|
_ = b.exec(civ.CmdModeDataFil, 0x01, b.curModeByte, dataByte, 0x01)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := b.exec(civ.CmdSplit, boolByte(on)); err != nil {
|
if err := b.exec(civ.CmdSplit, boolByte(on)); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
Reference in New Issue
Block a user