fix(tci): the drive commands need the TRX index, and the console holds its own clicks
Two faults, reported from a real SunSDR. DRIVE AND TUNE DRIVE DID NOTHING, and neither did MUTE. Those commands carry the transceiver index — 'drive:0,15;', not 'drive:15;' — and sent without it the radio ignores them silently: no error, no answer, the power unchanged. The rule was in the radio's own reports all along, which is where it should have been read from: it announces 'drive:0,85' and 'mute:0,false' at connect, while 'mic_level:100' and 'volume:-12' come with no index at all. Sending the shape the radio speaks in is the whole rule, and it is now written down next to the two exceptions. AGC LOOKED STUCK ON SLOW. The panel showed only what the radio reported back, on the principle that the radio is the truth — but ExpertSDR3 does not echo every setting it accepts, so a working button sat unlit. Changes are shown at once and held for a moment now; whatever the radio announces afterwards still wins, so a clamped or refused setting stays honest without every working one looking broken. Also from the same report, and fair: the consoles did not resemble each other. The Icom panel's RIT control is now a shared component both use — chip, signed offset, ± keys, wheel, and TYPING a value straight in, which is the thing a row of ±10/±100 buttons cannot do. Ctrl+←/→ shifts the RIT here as it does there. And LONG is gone from the AGC row: the protocol takes it, but it is a hang time nobody reaches for between overs.
This commit is contained in:
@@ -228,12 +228,22 @@ func (t *TCI) TCIPanel() TCIPanelState {
|
||||
// later.
|
||||
|
||||
// SetDrive sets the transmit drive, 0-100.
|
||||
func (t *TCI) SetDrive(v int) error { return t.send(fmt.Sprintf("drive:%d;", clampTCIPct(v))) }
|
||||
//
|
||||
// THE TRX INDEX IS PART OF THE COMMAND — "drive:0,15;", not "drive:15;". Sent
|
||||
// without it the radio simply ignores it: no error, no answer, the power
|
||||
// unchanged. The rule is the one the radio's own reports follow, and it was
|
||||
// there to read all along: this radio announces "drive:0,85" at connect.
|
||||
func (t *TCI) SetDrive(v int) error { return t.send(fmt.Sprintf("drive:0,%d;", clampTCIPct(v))) }
|
||||
|
||||
// SetTuneDrive sets the drive used by TUNE, 0-100.
|
||||
func (t *TCI) SetTuneDrive(v int) error { return t.send(fmt.Sprintf("tune_drive:%d;", clampTCIPct(v))) }
|
||||
// SetTuneDrive sets the drive used by TUNE, 0-100. Indexed, like drive.
|
||||
func (t *TCI) SetTuneDrive(v int) error {
|
||||
return t.send(fmt.Sprintf("tune_drive:0,%d;", clampTCIPct(v)))
|
||||
}
|
||||
|
||||
// SetMicLevel sets the microphone gain, 0-100.
|
||||
// Mic gain and volume are the two that are NOT indexed — the radio reports
|
||||
// them as "mic_level:100" and "volume:-12", with no receiver in front. Sending
|
||||
// the shape the radio speaks in is the whole rule here.
|
||||
func (t *TCI) SetMicLevel(v int) error { return t.send(fmt.Sprintf("mic_level:%d;", clampTCIPct(v))) }
|
||||
|
||||
// SetVolume sets the receive volume in dB. TCI's scale is negative — 0 is full
|
||||
@@ -248,8 +258,9 @@ func (t *TCI) SetVolume(db int) error {
|
||||
return t.send(fmt.Sprintf("volume:%d;", db))
|
||||
}
|
||||
|
||||
// SetMute mutes or unmutes the receiver.
|
||||
func (t *TCI) SetMute(on bool) error { return t.send(fmt.Sprintf("mute:%t;", on)) }
|
||||
// SetMute mutes or unmutes the receiver. Indexed — the radio reports
|
||||
// "mute:0,false", and a mute sent without the index goes nowhere.
|
||||
func (t *TCI) SetMute(on bool) error { return t.send(fmt.Sprintf("mute:0,%t;", on)) }
|
||||
|
||||
// SetAGC picks the AGC speed: off, long, slow, med, fast.
|
||||
func (t *TCI) SetAGC(mode string) error {
|
||||
|
||||
Reference in New Issue
Block a user