feat: New buttons for Icom Scope
This commit is contained in:
@@ -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