On its CAT/AUX connector an ACOM is the MASTER: it polls a transceiver and changes band from the reply, so nothing can be pushed to it. internal/catemu answers those polls on a second serial port, in ACOM command set 5 (Kenwood / Elecraft): FA;, FB;, IF; and ID;, and nothing else — a wrong-length reply is worse than none, it desynchronises the amp's parser for the following poll. Also offered for SPE. Some amps do not poll at all but read the radio↔PC CAT line in parallel; those never hear a responder, so an optional unprompted send (500/1000 ms) covers them. The TX frequency is what is sent: in split the amp must be tuned where we transmit. Frame lengths are pinned by tests — the failure they guard against is silent and only shows up as an amp that mistunes. Untested on hardware.
46 lines
1.5 KiB
Go
46 lines
1.5 KiB
Go
package catemu
|
|
|
|
import "testing"
|
|
|
|
// The reply LENGTHS are the contract: an amplifier parses these frames by
|
|
// fixed offsets, so a frame one character short desynchronises its parser for
|
|
// every following poll. Pin them.
|
|
func TestReplyShapes(t *testing.T) {
|
|
s := New(Config{ComPort: "COM99", Baud: 9600}, nil)
|
|
s.SetFrequency(14025000)
|
|
s.SetMode("CW")
|
|
|
|
if got := s.ifFrame(14025000); len(got) != 38 {
|
|
t.Errorf("IF frame is %d chars, want 38: %q", len(got), got)
|
|
}
|
|
// TS-2000 IF: "IF" then the 11-digit frequency in Hz.
|
|
if got := s.ifFrame(14025000); got[:13] != "IF00014025000" {
|
|
t.Errorf("IF frame frequency field = %q", got[:13])
|
|
}
|
|
if got := s.ifFrame(14025000); got[len(got)-1] != ';' {
|
|
t.Errorf("IF frame not terminated by ';': %q", got)
|
|
}
|
|
// Mode digit sits at P9, right after freq(11)+step(4)+rit(6)+3+2+1 — index 29 in the frame.
|
|
if got := s.ifFrame(14025000)[29]; got != '3' {
|
|
t.Errorf("CW mode digit = %q, want '3'", got)
|
|
}
|
|
s.SetMode("FT8") // data rides on SSB as far as an amp cares
|
|
if got := s.ifFrame(14074000)[29]; got != '2' {
|
|
t.Errorf("FT8 mode digit = %q, want '2'", got)
|
|
}
|
|
}
|
|
|
|
func TestModeDigit(t *testing.T) {
|
|
cases := map[string]byte{
|
|
"CW": '3', "CW-R": '3', "LSB": '1', "USB": '2', "SSB": '2',
|
|
"FM": '4', "AM": '5', "RTTY": '6', "": '2', "FT8": '2',
|
|
}
|
|
for mode, want := range cases {
|
|
s := New(Config{}, nil)
|
|
s.SetMode(mode)
|
|
if got := s.modeDigit(); got != want {
|
|
t.Errorf("mode %q → %q, want %q", mode, got, want)
|
|
}
|
|
}
|
|
}
|