feat: Icom split auto
This commit is contained in:
@@ -615,8 +615,22 @@ func (b *IcomSerial) scopeLoop(spec chan civ.Decoded, done chan struct{}) {
|
||||
// edges and take the rest as the trace, then publish immediately.
|
||||
// (USB splits this across 21 frames; the net rig sends it as one.)
|
||||
if len(region) >= 11 {
|
||||
low := civ.BCDToFreq(region[1:6])
|
||||
high := civ.BCDToFreq(region[6:11])
|
||||
// Net single-frame layout (IC-7610): region = [info 1B][freq1 5-BCD]
|
||||
// [freq2 5-BCD][amplitude bytes]. The two freq fields depend on the
|
||||
// scope mode: FIXED sends [low-edge][high-edge] (both absolute), CENTRE
|
||||
// sends [centre][span]. Tell them apart by magnitude — a second value
|
||||
// BIGGER than the first is a real high edge; a small one is a span
|
||||
// (e.g. 14.200 MHz + 100 kHz → centred 14.150-14.250; 21.000 +
|
||||
// 21.070 → fixed 21.000-21.070). Guessing wrong here gave the absurd
|
||||
// 21.000-42.070 span (low + a 21 MHz "span").
|
||||
v1 := civ.BCDToFreq(region[1:6])
|
||||
v2 := civ.BCDToFreq(region[6:11])
|
||||
var low, high int64
|
||||
if v2 > v1 {
|
||||
low, high = v1, v2 // absolute low/high edges (fixed edge set)
|
||||
} else {
|
||||
low, high = v1-v2/2, v1+v2/2 // centre + span (centre-on-VFO)
|
||||
}
|
||||
amp := append([]byte(nil), region[11:]...)
|
||||
b.scopeMu.Lock()
|
||||
b.scopeLow, b.scopeHigh = low, high
|
||||
@@ -627,10 +641,10 @@ func (b *IcomSerial) scopeLoop(spec chan civ.Decoded, done chan struct{}) {
|
||||
b.scopeMu.Unlock()
|
||||
if firstLog {
|
||||
head := region
|
||||
if len(head) > 24 {
|
||||
head = head[:24]
|
||||
if len(head) > 16 {
|
||||
head = head[:16]
|
||||
}
|
||||
applog.Printf("icom scope (net 1-frame): region=%dB head=[% X] → edges %d..%d Hz points=%d", len(region), head, low, high, len(amp))
|
||||
applog.Printf("icom scope (net 1-frame): head=[% X] v1=%d v2=%d → %d..%d Hz points=%d", head, v1, v2, low, high, len(amp))
|
||||
}
|
||||
}
|
||||
continue
|
||||
@@ -1356,6 +1370,24 @@ func (b *IcomSerial) SetMicGain(p int) error {
|
||||
}
|
||||
|
||||
func (b *IcomSerial) SetIcomSplit(on bool) error {
|
||||
if on {
|
||||
// Enable split with the usual "work him up" TX offset: +1 kHz on CW,
|
||||
// +5 kHz otherwise (SSB). Set the unselected (TX) VFO to RX+offset first,
|
||||
// then turn split on. 0x25 0x01 + BCD sets the unselected VFO's frequency.
|
||||
rx := b.curFreq
|
||||
if rx <= 0 {
|
||||
if hz, err := b.readFreq(); err == nil {
|
||||
rx = hz
|
||||
}
|
||||
}
|
||||
if rx > 0 {
|
||||
offset := int64(5000)
|
||||
if b.curModeByte == civ.ModeCW || b.curModeByte == civ.ModeCWR {
|
||||
offset = 1000
|
||||
}
|
||||
_ = b.exec(append([]byte{civ.CmdVfoFreq, civ.SubVfoUnselected}, civ.FreqToBCD(rx+offset)...)...)
|
||||
}
|
||||
}
|
||||
if err := b.exec(civ.CmdSplit, boolByte(on)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user