fix(yaesu): mic gain scale, 200 W models, and a NAR button that did nothing
Reported from a real FTDX101, and each one is a different kind of wrong. MIC GAIN was read and written through the 0-255 scale the audio gains use, but the CAT reference gives MG000-100. A rig set to 80 therefore showed 38, and moving the slider sent 204 — outside the range the radio accepts, so it refused the command and the slider sprang back. That snap-back was the symptom; the scale was the cause. POWER was capped at 100 W by the slider, not by the radio. There is no CAT command for 'how much power can you make', so the ceiling comes from the model name, with the rig believed if it ever reports more than the table expects — it has just proved what it can do. NAR is the narrow IF filter, and on a rig that does not implement NA the button showed a state the radio never gave and did nothing when pressed, which reads as a fault in the radio. Now shown only when the rig answers, with a tooltip saying what it is. Also: the frequency readout steps the Hz digits under the wheel, not just the kHz ones. Zero-beating a CW signal is a few tens of Hz and it was the one move the display would not make. And the split chaser is CW-only — its marker comes from a CW skimmer.
This commit is contained in:
@@ -43,7 +43,15 @@ type YaesuTXState struct {
|
||||
PowerMeter int `json:"power_meter"` // 0-100, TX only
|
||||
SWRMeter int `json:"swr_meter"` // 0-100, TX only
|
||||
|
||||
RFPower int `json:"rf_power"` // watts
|
||||
RFPower int `json:"rf_power"` // watts
|
||||
// MaxPower is what this model can actually be set to, so the slider stops
|
||||
// where the radio does. An FTDX101MP is a 200 W transmitter and its operator
|
||||
// could not ask for more than 100 W — the slider, not the rig, was the limit.
|
||||
MaxPower int `json:"max_power"`
|
||||
// NarrowSupported says the rig answered NA at all. A button that reports a
|
||||
// state the radio never gave, and does nothing when pressed, is worse than
|
||||
// an absent one: it looks like a fault in the radio.
|
||||
NarrowSupported bool `json:"narrow_supported"`
|
||||
MicGain int `json:"mic_gain"` // 0-100
|
||||
AFGain int `json:"af_gain"` // 0-100
|
||||
RFGain int `json:"rf_gain"` // 0-100
|
||||
@@ -110,9 +118,29 @@ func (y *Yaesu) YaesuState() YaesuTXState {
|
||||
st := y.panel
|
||||
st.Available = y.port != nil
|
||||
st.Model = y.model
|
||||
st.MaxPower = yaesuMaxPower(y.model, st.RFPower)
|
||||
return st
|
||||
}
|
||||
|
||||
// yaesuMaxPower is how far the power slider may go on this model.
|
||||
//
|
||||
// The rig itself is never asked — there is no CAT command for "how much power
|
||||
// can you make" — so it comes from the model name, with one safeguard: a rig
|
||||
// REPORTING more than the table expects is believed, because it has just proved
|
||||
// what it can do. Anything unknown gets 100 W, which is the family default and
|
||||
// errs towards asking for too little.
|
||||
func yaesuMaxPower(model string, reported int) int {
|
||||
max := 100
|
||||
switch {
|
||||
case strings.Contains(model, "101MP"), strings.Contains(model, "5000"), strings.Contains(model, "9000"):
|
||||
max = 200
|
||||
}
|
||||
if reported > max {
|
||||
max = reported
|
||||
}
|
||||
return max
|
||||
}
|
||||
|
||||
// readPanel refreshes the meters, and the settings on the slower beat. Called
|
||||
// from ReadState with the mutex HELD, so it shares the same serialised link.
|
||||
func (y *Yaesu) readPanel(mode string, split bool, txHz int64) {
|
||||
@@ -226,8 +254,15 @@ func (y *Yaesu) readPanelSettings() {
|
||||
if v, ok := y.askNum("PC;", "PC", 3); ok {
|
||||
y.panel.RFPower = v // watts, not a 0-255 scale
|
||||
}
|
||||
// MIC GAIN IS 0-100, not 0-255.
|
||||
//
|
||||
// It was read through the 0-255 scale like the audio gains, so an FTDX101
|
||||
// set to 80 showed 38 — and worse, writing sent 80 → 204, outside the range
|
||||
// the rig accepts, so the setting was refused and the slider sprang back to
|
||||
// where it had been. Reported from a real FTDX101; the CAT reference gives
|
||||
// MG000-100 for the whole current family.
|
||||
if v, ok := y.askNum("MG;", "MG", 3); ok {
|
||||
y.panel.MicGain = scale255(v)
|
||||
y.panel.MicGain = clampInt(v, 0, 100)
|
||||
}
|
||||
if v, ok := y.askNum("AG0;", "AG0", 3); ok {
|
||||
y.panel.AFGain = scale255(v)
|
||||
@@ -276,6 +311,7 @@ func (y *Yaesu) readPanelSettings() {
|
||||
}
|
||||
if v, ok := y.askNum("NA0;", "NA0", 1); ok {
|
||||
y.panel.Narrow = v != 0
|
||||
y.panel.NarrowSupported = true
|
||||
}
|
||||
if v, ok := y.askNum("VX;", "VX", 1); ok {
|
||||
y.panel.VOX = v != 0
|
||||
@@ -356,7 +392,7 @@ func (y *Yaesu) SetYaesuPower(w int) error {
|
||||
}
|
||||
|
||||
func (y *Yaesu) SetYaesuMicGain(p int) error {
|
||||
return y.setAndRefresh(fmt.Sprintf("MG%03d;", from100(p)))
|
||||
return y.setAndRefresh(fmt.Sprintf("MG%03d;", clampInt(p, 0, 100)))
|
||||
}
|
||||
|
||||
func (y *Yaesu) SetYaesuAFGain(p int) error {
|
||||
|
||||
Reference in New Issue
Block a user