chore: release v0.21.3
This commit is contained in:
+44
-23
@@ -39,10 +39,10 @@ const (
|
||||
CmdReadID = 0x19 // sub 0x00 = rig's own CI-V address (identifies model)
|
||||
CmdPower = 0x18 // power on/off (sub 0x01 = on, 0x00 = off; on needs an FE wake preamble)
|
||||
|
||||
CmdAnt = 0x12 // antenna selector (sub 0x00 = ANT1, 0x01 = ANT2; read = no sub)
|
||||
CmdAtt = 0x11 // attenuator (1 BCD byte of dB; 0x00 = off)
|
||||
CmdLevel = 0x14 // analogue levels (sub + 2 BCD bytes, 0000-0255)
|
||||
CmdMeter = 0x15 // meters (sub + 2 BCD bytes, 0000-0255): S-meter/Po/SWR
|
||||
CmdAnt = 0x12 // antenna selector (sub 0x00 = ANT1, 0x01 = ANT2; read = no sub)
|
||||
CmdAtt = 0x11 // attenuator (1 BCD byte of dB; 0x00 = off)
|
||||
CmdLevel = 0x14 // analogue levels (sub + 2 BCD bytes, 0000-0255)
|
||||
CmdMeter = 0x15 // meters (sub + 2 BCD bytes, 0000-0255): S-meter/Po/SWR
|
||||
CmdSwitch = 0x16 // on/off + multi-state DSP settings (sub + 1 byte)
|
||||
CmdATU = 0x1C // sub 0x01 = antenna tuner (0x00 off, 0x01 through, 0x02 tune)
|
||||
CmdScope = 0x27 // spectrum-scope waveform stream (sub 0x00 = data, 0x11 = on/off)
|
||||
@@ -91,26 +91,26 @@ const (
|
||||
SubATU = 0x01 // antenna tuner (data 0x02 = start tune)
|
||||
|
||||
// CmdScope sub-commands.
|
||||
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)
|
||||
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)
|
||||
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
|
||||
SubSwAGC = 0x12 // 1=FAST, 2=MID, 3=SLOW
|
||||
SubSwNB = 0x22 // noise blanker on/off
|
||||
SubSwNR = 0x40 // noise reduction on/off
|
||||
SubSwANF = 0x41 // auto-notch on/off
|
||||
SubSwComp = 0x44 // speech compressor on/off
|
||||
SubSwMon = 0x45 // monitor on/off
|
||||
SubSwVOX = 0x46 // VOX on/off
|
||||
SubSwPreamp = 0x02 // 0=off, 1=P.AMP1, 2=P.AMP2
|
||||
SubSwAGC = 0x12 // 1=FAST, 2=MID, 3=SLOW
|
||||
SubSwNB = 0x22 // noise blanker on/off
|
||||
SubSwNR = 0x40 // noise reduction on/off
|
||||
SubSwANF = 0x41 // auto-notch on/off
|
||||
SubSwComp = 0x44 // speech compressor on/off
|
||||
SubSwMon = 0x45 // monitor on/off
|
||||
SubSwVOX = 0x46 // VOX on/off
|
||||
SubSwBreakIn = 0x47 // CW break-in: 0=OFF, 1=SEMI, 2=FULL (needed so 0x17 CW keys TX)
|
||||
SubSwMN = 0x48 // manual notch on/off
|
||||
SubSwAPF = 0x32 // audio peak filter on/off (CW only)
|
||||
SubSwMN = 0x48 // manual notch on/off
|
||||
SubSwAPF = 0x32 // audio peak filter on/off (CW only)
|
||||
)
|
||||
|
||||
// CW break-in modes (CmdSwitch 0x47).
|
||||
@@ -307,22 +307,43 @@ func ModeToADIF(m byte, data bool) string {
|
||||
|
||||
// ModelName maps a rig's default CI-V address (from CmdReadID) to a readable
|
||||
// model. Unknown addresses fall back to a hex label.
|
||||
//
|
||||
// The name is not cosmetic: the UI derives model-dependent behaviour from it —
|
||||
// notably the attenuator steps, which are 6/12/18 dB on the big rigs and a single
|
||||
// 20 dB on the small ones. An address missing here therefore shows the WRONG
|
||||
// attenuator buttons, and the rig NAKs them.
|
||||
//
|
||||
// Two entries here used to be wrong in a way that pointed at each other: 0x80 was
|
||||
// labelled IC-7800 (it is the IC-7410) and 0x88 IC-7700 (it is the IC-7100), while
|
||||
// the real IC-7800 (0x6A) and IC-7700 (0x74) were absent — so a 7800 came up as
|
||||
// "Icom (0x6A)" with a 20 dB attenuator it does not have.
|
||||
//
|
||||
// Addresses cross-checked against the TR4W CI-V table and an independent
|
||||
// published list; both agree on every value below.
|
||||
func ModelName(addr byte) string {
|
||||
switch addr {
|
||||
case 0x6A:
|
||||
return "IC-7800"
|
||||
case 0x74:
|
||||
return "IC-7700"
|
||||
case 0x7A:
|
||||
return "IC-7600"
|
||||
case 0x7C:
|
||||
return "IC-9100"
|
||||
case 0x80:
|
||||
return "IC-7410"
|
||||
case 0x88:
|
||||
return "IC-7100"
|
||||
case 0x8E:
|
||||
return "IC-7851" // shared with the IC-7850
|
||||
case 0x94:
|
||||
return "IC-7300"
|
||||
case 0x98:
|
||||
return "IC-7610"
|
||||
case 0x7C:
|
||||
return "IC-9100"
|
||||
case 0xA2:
|
||||
return "IC-9700"
|
||||
case 0xA4:
|
||||
return "IC-705"
|
||||
case 0x88:
|
||||
return "IC-7700"
|
||||
case 0x80:
|
||||
return "IC-7800"
|
||||
}
|
||||
return fmt.Sprintf("Icom (0x%02X)", addr)
|
||||
}
|
||||
|
||||
@@ -55,8 +55,8 @@ func TestScanSingleFreqResponse(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestScanSkipsEchoAndKeepsPartial(t *testing.T) {
|
||||
echo := Frame(0x98, AddrController, CmdReadFreq) // our outgoing (echoed back)
|
||||
resp := Frame(AddrController, 0x98, CmdReadMode, ModeCW, 0x01) // a real response
|
||||
echo := Frame(0x98, AddrController, CmdReadFreq) // our outgoing (echoed back)
|
||||
resp := Frame(AddrController, 0x98, CmdReadMode, ModeCW, 0x01) // a real response
|
||||
buf := append(append([]byte{}, echo...), resp...)
|
||||
buf = append(buf, 0xFE, 0xFE, 0x98) // a partial third frame (no FD yet)
|
||||
|
||||
@@ -130,3 +130,35 @@ func TestModelName(t *testing.T) {
|
||||
t.Errorf("ModelName(0x12) = %q, want fallback", got)
|
||||
}
|
||||
}
|
||||
|
||||
// CI-V addresses are hardware constants: a wrong one means the console shows the
|
||||
// wrong model, and with it the wrong attenuator steps (6/12/18 dB on the big
|
||||
// rigs, a single 20 dB on the small ones) — buttons the rig then NAKs.
|
||||
//
|
||||
// Two entries here were previously wrong in a way that pointed at each other:
|
||||
// 0x80 was labelled IC-7800 (it is the IC-7410) and 0x88 IC-7700 (it is the
|
||||
// IC-7100), while the real IC-7800 (0x6A) and IC-7700 (0x74) were missing — so an
|
||||
// IC-7800 came up as "Icom (0x6A)" with a 20 dB attenuator it does not have.
|
||||
func TestModelNameAddresses(t *testing.T) {
|
||||
for addr, want := range map[byte]string{
|
||||
0x6A: "IC-7800",
|
||||
0x74: "IC-7700",
|
||||
0x7A: "IC-7600",
|
||||
0x7C: "IC-9100",
|
||||
0x80: "IC-7410",
|
||||
0x88: "IC-7100",
|
||||
0x8E: "IC-7851",
|
||||
0x94: "IC-7300",
|
||||
0x98: "IC-7610",
|
||||
0xA2: "IC-9700",
|
||||
0xA4: "IC-705",
|
||||
} {
|
||||
if got := ModelName(addr); got != want {
|
||||
t.Errorf("ModelName(0x%02X) = %q, want %q", addr, got, want)
|
||||
}
|
||||
}
|
||||
// An unknown address must stay identifiable rather than masquerade as a model.
|
||||
if got := ModelName(0x42); got != "Icom (0x42)" {
|
||||
t.Errorf("ModelName(0x42) = %q, want the hex fallback", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user