feat(cat): per-rig Kenwood/Elecraft data-mode choice (USB / MD6 / keep)
No single Kenwood mode digit fits every rig for a data mode: a K3/K4 wants DATA (MD6), a TS-590SG/TS-990S data mode is a USB modifier set on the rig, and MD6 on a plain Kenwood is FSK/RTTY. So the operator now chooses in Settings → CAT: USB (default), DATA (MD6), or leave the rig's mode unchanged. Only soundcard/data modes (FT8, PSK, JT…) follow this; RTTY/FSK stays its own native mode, and voice/CW are untouched (isKenwoodDataMode + test).
This commit is contained in:
@@ -56,6 +56,12 @@ type Kenwood struct {
|
||||
// a wire, which is how most operators actually put a rig on the network.
|
||||
host string
|
||||
digital string // mode name logged for data (FT8 by default)
|
||||
// dataMode chooses what CAT mode a DATA/digital mode (FT8, PSK…) sets, because
|
||||
// no single Kenwood mode digit is right for every rig: "usb" → USB (the SSB-data
|
||||
// base, default), "data" → the DATA mode digit MD6 (Elecraft K3/K4), "keep" →
|
||||
// leave the rig's current mode untouched (safest for a TS-590SG/TS-990S whose
|
||||
// data mode is a USB modifier the operator sets on the rig). See SetMode.
|
||||
dataMode string
|
||||
|
||||
mu sync.Mutex
|
||||
port serial.Port
|
||||
@@ -360,6 +366,17 @@ func (k *Kenwood) SetMode(mode string) error {
|
||||
if k.port == nil {
|
||||
return fmt.Errorf("kenwood: not connected")
|
||||
}
|
||||
// Honour the operator's DATA-mode preference for a digital mode. No single
|
||||
// mode digit fits every rig, so the operator picks: keep the rig's mode, use
|
||||
// MD6 (K3/K4 DATA), or fall through to the default USB from kenwoodModeDigit.
|
||||
if isKenwoodDataMode(mode) {
|
||||
switch k.dataMode {
|
||||
case "keep":
|
||||
return nil // leave whatever data mode the operator set on the rig
|
||||
case "data":
|
||||
return k.write("MD6;") // Elecraft K3/K4 DATA mode
|
||||
}
|
||||
}
|
||||
d := kenwoodModeDigit(mode, k.curFreq)
|
||||
if d == 0 {
|
||||
return fmt.Errorf("kenwood: no CAT mode for %q", mode)
|
||||
@@ -367,6 +384,25 @@ func (k *Kenwood) SetMode(mode string) error {
|
||||
return k.write(fmt.Sprintf("MD%c;", d))
|
||||
}
|
||||
|
||||
// SetDataMode configures how a DATA/digital mode is set: "usb" (default), "data"
|
||||
// (MD6, Elecraft K3/K4) or "keep" (don't change the rig's mode).
|
||||
func (k *Kenwood) SetDataMode(m string) {
|
||||
k.mu.Lock()
|
||||
k.dataMode = strings.ToLower(strings.TrimSpace(m))
|
||||
k.mu.Unlock()
|
||||
}
|
||||
|
||||
// isKenwoodDataMode reports whether a mode name is a soundcard/data mode (FT8,
|
||||
// PSK, JT…) rather than a voice/CW/RTTY mode the rig sets natively.
|
||||
func isKenwoodDataMode(mode string) bool {
|
||||
switch strings.ToUpper(strings.TrimSpace(mode)) {
|
||||
case "", "LSB", "USB", "SSB", "CW", "CW-R", "CWR", "FM", "NFM", "AM",
|
||||
"RTTY", "FSK", "RTTY-R", "FSK-R":
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (k *Kenwood) SetPTT(on bool) error {
|
||||
k.mu.Lock()
|
||||
defer k.mu.Unlock()
|
||||
|
||||
@@ -111,6 +111,23 @@ func TestKenwoodModeDigit(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The DATA-mode preference only applies to soundcard/data modes, never to voice,
|
||||
// CW or native RTTY — getting this wrong would hijack an SSB or CW mode change.
|
||||
func TestIsKenwoodDataMode(t *testing.T) {
|
||||
data := []string{"FT8", "FT4", "PSK31", "JT65", "DATA", "DIGITAL", "OLIVIA"}
|
||||
notData := []string{"", "LSB", "USB", "SSB", "CW", "CW-R", "FM", "AM", "RTTY", "FSK", "RTTY-R"}
|
||||
for _, m := range data {
|
||||
if !isKenwoodDataMode(m) {
|
||||
t.Errorf("isKenwoodDataMode(%q) = false, want true", m)
|
||||
}
|
||||
}
|
||||
for _, m := range notData {
|
||||
if isKenwoodDataMode(m) {
|
||||
t.Errorf("isKenwoodDataMode(%q) = true, want false", m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// What the log records for each mode digit the rig reports.
|
||||
func TestKenwoodModeToADIF(t *testing.T) {
|
||||
cases := []struct {
|
||||
|
||||
Reference in New Issue
Block a user