chore(spe): make a failed power-on say where it failed

"The ON button does nothing" has three different causes — the modem-line pulse
was refused, the pulse went out and the amplifier ignored it, or the amplifier
woke and the UI missed it — and the log could not separate them: it recorded
one combined error and never said whether the amp came up.

RTS and DTR are now reported separately (not every USB-serial chip honours the
modem lines, and some refuse them without saying so), alongside the model and
transport. A watcher then logs whether the amplifier answered within 15
seconds, off the caller's goroutine so the click still returns at once.

No change to the wake sequence itself, which is the part that took a long time
to get right on the 1.3K-FA.
This commit is contained in:
2026-08-13 09:29:53 +02:00
parent ed3c132f70
commit 6aff322be6
+30 -2
View File
@@ -220,9 +220,17 @@ func (c *Client) PowerOn() error {
time.Sleep(wakePulse) time.Sleep(wakePulse)
return set(true) return set(true)
} }
if err = pulse(sp.SetRTS); err == nil { // Each line reported separately. Not every USB-serial chip honours the modem
err = pulse(sp.SetDTR) // lines, and some refuse them without saying so — on an amplifier that never
// wakes, "which of the two failed, or neither" is the whole diagnosis, and a
// single combined error cannot give it.
rtsErr := pulse(sp.SetRTS)
dtrErr := pulse(sp.SetDTR)
if err = rtsErr; err == nil {
err = dtrErr
} }
applog.Printf("spe: power ON pulse on %s (model=%q transport=%s) — RTS err=%v, DTR err=%v",
c.cfg.ComPort, c.GetStatus().Model, c.cfg.Transport, rtsErr, dtrErr)
// Booting, the amp re-enumerates its USB interface, which leaves this handle // Booting, the amp re-enumerates its USB interface, which leaves this handle
// pointing at a device that no longer exists — the amp came up and OpsLog // pointing at a device that no longer exists — the amp came up and OpsLog
// still read "offline". Drop it; the poll loop reopens a fresh one as soon as // still read "offline". Drop it; the poll loop reopens a fresh one as soon as
@@ -231,6 +239,26 @@ func (c *Client) PowerOn() error {
c.dropLocked() c.dropLocked()
c.mu.Unlock() c.mu.Unlock()
applog.Printf("spe: power ON — RTS then DTR pulsed on %s (err=%v)", c.cfg.ComPort, err) applog.Printf("spe: power ON — RTS then DTR pulsed on %s (err=%v)", c.cfg.ComPort, err)
// Say whether it actually woke. "The ON button does nothing" is a report with
// three different causes — the pulse was refused, the pulse went out and the
// amp ignored it, or the amp came up and the UI missed it — and only the log
// can separate them. Watched off the caller's goroutine so the click returns
// at once.
go func() {
deadline := time.Now().Add(15 * time.Second)
for time.Now().Before(deadline) {
time.Sleep(time.Second)
if c.GetStatus().Connected {
applog.Printf("spe: power ON — amp answered after %.0fs",
15-time.Until(deadline).Seconds())
return
}
}
applog.Printf("spe: power ON — no answer within 15s on %s. The pulse was sent; "+
"either this amplifier does not wake on RTS/DTR, or the adapter does not drive those lines",
c.cfg.ComPort)
}()
return err return err
} }