feat: New buttons for Icom Scope
This commit is contained in:
+4
-3
@@ -458,9 +458,10 @@ type IcomController interface {
|
||||
SetMicGain(int) error
|
||||
SetIcomSplit(bool) error
|
||||
TuneATU() error
|
||||
SetScope(bool) error // enable/disable the spectrum-scope waveform stream
|
||||
SetScopeMode(bool) error // true = fixed span, false = center-on-VFO
|
||||
ScopeData() ScopeSweep // latest assembled sweep (empty until enabled)
|
||||
SetScope(bool) error // enable/disable the spectrum-scope waveform stream
|
||||
SetScopeMode(bool) error // true = fixed span, false = center-on-VFO
|
||||
SetScopeEdges(int64, int64) error // point the fixed scope at low..high Hz (centre/pan)
|
||||
ScopeData() ScopeSweep // latest assembled sweep (empty until enabled)
|
||||
SetRIT(int) error // RIT/ΔTX offset in signed Hz
|
||||
SetRITOn(bool) error // RIT on/off
|
||||
SetXITOn(bool) error // ΔTX (XIT) on/off
|
||||
|
||||
@@ -94,9 +94,10 @@ const (
|
||||
SubScopeData = 0x00 // waveform data frame (divided across several frames)
|
||||
SubScopeOnOff = 0x10 // turn the scope display itself on/off (00/01)
|
||||
SubScopeOn = 0x11 // enable/disable waveform data output over CI-V (00/01)
|
||||
SubScopeMode = 0x14 // center/fixed mode (0=center, 1=fixed) — VERIFY on rig
|
||||
SubScopeSpan = 0x15 // span in center mode — VERIFY on rig
|
||||
SubScopeEdge = 0x16 // fixed-mode edge frequencies — VERIFY on rig
|
||||
SubScopeMode = 0x14 // center/fixed mode (0=center, 1=fixed)
|
||||
SubScopeSpan = 0x15 // span in center mode (±span/2 as 5 LE-BCD)
|
||||
SubScopeEdge = 0x16 // fixed-mode ACTIVE edge set 1-4 (vfo + set#)
|
||||
SubScopeFixEdge = 0x1e // fixed-mode edge FREQUENCIES: [range][set#][low 5-BCD][high 5-BCD]
|
||||
|
||||
// CmdSwitch sub-commands.
|
||||
SubSwPreamp = 0x02 // 0=off, 1=P.AMP1, 2=P.AMP2
|
||||
|
||||
@@ -750,6 +750,58 @@ func (b *IcomSerial) SetScopeMode(fixed bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// icScopeRanges maps a frequency to the IC-7610's spectrum edge-frequency range
|
||||
// id (from Hamlib's ic7610 caps). SetScopeEdges needs it to address the right
|
||||
// fixed-edge memory. Each range spans a chunk of the tuning range.
|
||||
var icScopeRanges = []struct {
|
||||
lo, hi int64
|
||||
id byte
|
||||
}{
|
||||
{30_000, 1_600_000, 1}, {1_600_000, 2_000_000, 2}, {2_000_000, 6_000_000, 3},
|
||||
{6_000_000, 8_000_000, 4}, {8_000_000, 11_000_000, 5}, {11_000_000, 15_000_000, 6},
|
||||
{15_000_000, 20_000_000, 7}, {20_000_000, 22_000_000, 8}, {22_000_000, 26_000_000, 9},
|
||||
{26_000_000, 30_000_000, 10}, {30_000_000, 45_000_000, 11}, {45_000_000, 60_000_000, 12},
|
||||
}
|
||||
|
||||
// scopeRangeBCD returns the range id (as a 1-byte BCD) for a frequency, or 0 if
|
||||
// out of range.
|
||||
func scopeRangeBCD(freq int64) byte {
|
||||
for _, r := range icScopeRanges {
|
||||
if freq >= r.lo && freq < r.hi {
|
||||
return byte(r.id/10)<<4 | byte(r.id%10) // 1-byte BCD (11 → 0x11)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// SetScopeEdges points the FIXED-mode scope at [low..high] by writing them into
|
||||
// the rig's fixed-edge memory (edge set 1) and making that set active. This is
|
||||
// how the panel's "centre on VFO" and pan ◀/▶ work: they just compute VFO±50 kHz
|
||||
// (and shift it) and set the edges — no dependence on the waveform decode. CI-V:
|
||||
// 0x27 0x14 fixed, 0x27 0x16 set 1 active, 0x27 0x1e [range][set][low][high].
|
||||
func (b *IcomSerial) SetScopeEdges(low, high int64) error {
|
||||
if low <= 0 || high <= low {
|
||||
return fmt.Errorf("icom scope: bad edges %d..%d", low, high)
|
||||
}
|
||||
rangeID := scopeRangeBCD((low + high) / 2)
|
||||
if rangeID == 0 {
|
||||
return fmt.Errorf("icom scope: freq out of range")
|
||||
}
|
||||
if b.dualScope {
|
||||
_ = b.exec(civ.CmdScope, civ.SubScopeMode, 0x00, 0x01) // fixed mode (main)
|
||||
_ = b.exec(civ.CmdScope, civ.SubScopeEdge, 0x00, 0x01) // activate edge set 1
|
||||
} else {
|
||||
_ = b.exec(civ.CmdScope, civ.SubScopeMode, 0x01)
|
||||
_ = b.exec(civ.CmdScope, civ.SubScopeEdge, 0x01)
|
||||
}
|
||||
payload := append([]byte{civ.CmdScope, civ.SubScopeFixEdge, rangeID, 0x01}, civ.FreqToBCD(low)...)
|
||||
payload = append(payload, civ.FreqToBCD(high)...)
|
||||
b.scopeMu.Lock()
|
||||
b.scopeFixed = true
|
||||
b.scopeMu.Unlock()
|
||||
return b.exec(payload...)
|
||||
}
|
||||
|
||||
// SetRIT sets the RIT/ΔTX offset (signed Hz, ±9999).
|
||||
func (b *IcomSerial) SetRIT(hz int) error {
|
||||
if err := b.exec(append([]byte{civ.CmdRIT, civ.SubRITFreq}, civ.RITToBCD(hz)...)...); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user