revert(icom): keep 0x27 0x11 as the scope data switch, log what the retry got
Hamlib documents the spectrum scope on the IC-785x, so a rejected 0x27 0x11 is not proof the command is missing — and taking 0x27 0x10 for the data switch would have blanked that operator's own scope screen when OpsLog disabled it. Both shapes were refused within 96 ms, so neither was a timeout, and guessing the next subcommand is how the last two rounds went. The retry now logs the second attempt's own error and the failure points at the CI-V trace.
This commit is contained in:
+17
-34
@@ -93,18 +93,15 @@ type IcomSerial struct {
|
||||
// leading main/sub selector byte (IC-7610/9700). scopeAmp is the latest
|
||||
// reassembled sweep; scopeMu guards it (written by the scope goroutine, read
|
||||
// via ScopeData from the binding goroutine).
|
||||
dualScope bool
|
||||
// Which 0x27 subcommand switches the waveform stream on this rig: 0x11 where
|
||||
// it exists, 0x10 on the ones that answer 0x11 with a rejection.
|
||||
scopeOutSub byte
|
||||
scopeMu sync.Mutex
|
||||
scopeAmp []byte
|
||||
scopeLow int64 // spectrum left-edge frequency (from the sweep's header frame)
|
||||
scopeHigh int64 // spectrum right-edge frequency
|
||||
scopeSeq int
|
||||
scopeOn bool
|
||||
scopeFixed bool // true = fixed-span mode (tracked optimistically)
|
||||
scopeSeen bool // logged the first sweep's structure once (on-rig verification)
|
||||
dualScope bool
|
||||
scopeMu sync.Mutex
|
||||
scopeAmp []byte
|
||||
scopeLow int64 // spectrum left-edge frequency (from the sweep's header frame)
|
||||
scopeHigh int64 // spectrum right-edge frequency
|
||||
scopeSeq int
|
||||
scopeOn bool
|
||||
scopeFixed bool // true = fixed-span mode (tracked optimistically)
|
||||
scopeSeen bool // logged the first sweep's structure once (on-rig verification)
|
||||
|
||||
curFreq int64 // last frequency read (for sideband choice)
|
||||
curModeByte byte // last raw Icom mode byte (for filter re-send)
|
||||
@@ -1023,7 +1020,10 @@ func (b *IcomSerial) execScope(what string, sub byte, args ...byte) error {
|
||||
if err == nil || !strings.Contains(err.Error(), "rejected") {
|
||||
return err
|
||||
}
|
||||
if err2 := try(!b.dualScope); err2 == nil {
|
||||
err2 := try(!b.dualScope)
|
||||
applog.Printf("icom scope: %s rejected in the %s form — the other form gave: %v",
|
||||
what, map[bool]string{true: "27 xx 00 …", false: "27 xx …"}[b.dualScope], err2)
|
||||
if err2 == nil {
|
||||
b.dualScope = !b.dualScope
|
||||
applog.Printf("icom scope: %s rejected — this rig wants the %s form (selector=%v)",
|
||||
what, map[bool]string{true: "27 xx 00 …", false: "27 xx …"}[b.dualScope], b.dualScope)
|
||||
@@ -1050,32 +1050,15 @@ func (b *IcomSerial) SetScope(on bool) error {
|
||||
// radio, and closing OpsLog (SetScope(false)) blanking a local IC-7300's
|
||||
// screen is exactly the regression this avoids. Some firmwares don't ack a
|
||||
// 0x27 set; a timeout isn't fatal, so log and continue.
|
||||
if b.scopeOutSub != civ.SubScopeOnOff {
|
||||
if err := b.execScope("display on", civ.SubScopeOnOff, 0x01); err != nil {
|
||||
applog.Printf("icom scope: display on ack: %v", err)
|
||||
}
|
||||
if err := b.execScope("display on", civ.SubScopeOnOff, 0x01); err != nil {
|
||||
applog.Printf("icom scope: display on ack: %v", err)
|
||||
}
|
||||
}
|
||||
// Waveform data OUTPUT over CI-V: enabled with the scope, and — crucially —
|
||||
// the ONLY thing we switch off on disable, so the radio's own scope display is
|
||||
// left exactly as the operator had it.
|
||||
//
|
||||
// scopeOutSub is 0x11 on the radios that have it. The IC-7851 does not: it
|
||||
// rejects 0x11 in both shapes, because on that radio 0x27 0x10 is itself the
|
||||
// waveform-output switch rather than a display switch. Fall back to it, and
|
||||
// from then on switch it off on disable too — on THAT radio doing so stops a
|
||||
// data stream, not the operator's own scope screen.
|
||||
if b.scopeOutSub == 0 {
|
||||
b.scopeOutSub = civ.SubScopeOn
|
||||
}
|
||||
err := b.execScope("data output", b.scopeOutSub, boolByte(on))
|
||||
if err != nil && b.scopeOutSub == civ.SubScopeOn && strings.Contains(err.Error(), "rejected") {
|
||||
applog.Printf("icom scope: no 0x27 0x11 on this rig — 0x27 0x10 is its data-output switch")
|
||||
b.scopeOutSub = civ.SubScopeOnOff
|
||||
err = b.execScope("data output", b.scopeOutSub, boolByte(on))
|
||||
}
|
||||
if err != nil {
|
||||
applog.Printf("icom scope: output on=%v ack: %v", on, err)
|
||||
if err := b.execScope("data output", civ.SubScopeOn, boolByte(on)); err != nil {
|
||||
applog.Printf("icom scope: output on=%v ack: %v — turn the CI-V trace on (Settings → CAT) and send the log", on, err)
|
||||
}
|
||||
b.scopeMu.Lock()
|
||||
b.scopeOn = on
|
||||
|
||||
Reference in New Issue
Block a user