feat(winkeyer): K3NG keyers, and wait out their reboot
The operator's keyer is a K3NG — an Arduino running an emulation of the WinKeyer protocol — which changes the diagnosis and nearly broke it. Checked against K3NG's own source before anything else, because yesterday's handshake now FAILS a connect where it used to press on regardless. It is safe: k3ng_keyer.ino implements admin echo (0x04) and echoes the byte back, 0x13 is a documented no-op, and OPTION_WINKEY_STRICT_HOST_OPEN — on by default — ignores every byte except 0x00 before host open, so the resync nulls are dropped harmlessly and the echo probe still gets through. The real cause is in K3NG's options file, beside the feature itself: "disabling Automatic Software Reset is highly recommended", and an option to "discard errant serial port bytes at startup" for when it is not. On an Arduino, DTR is wired to reset through a capacitor: opening the port reboots the board into its bootloader. Ours spoke 400 ms later, to a keyer that was not running yet. So the retry now waits 2.5 s, which recovers it without an operator pressing connect twice, and the engine list gains a K3NG entry that skips the doomed fast attempt altogether. Everything else is identical to a K1EL — same settings panel, same protocol.
This commit is contained in:
@@ -53,6 +53,8 @@ type Config struct {
|
||||
|
||||
// Type selects the keyer engine on this serial port:
|
||||
// "" / "k1el" → a K1EL WinKeyer chip (the default, everything above applies)
|
||||
// "k3ng" → a K3NG keyer: an Arduino running the same protocol. Identical
|
||||
// once open; it just needs time to reboot when the port opens.
|
||||
// "serial" → the PC bit-bangs Morse on a control line (no WinKeyer chip):
|
||||
// the "hardware CW keying" a Yaesu SCU-17 / generic interface
|
||||
// uses. WPM / Weight / Farnsworth / LeadIn / Tail / UsePTT still
|
||||
@@ -164,7 +166,9 @@ func (m *Manager) Connect(cfg Config) error {
|
||||
return fmt.Errorf("winkeyer: open %s: %w", cfg.Port, err)
|
||||
}
|
||||
|
||||
ver, err := hostOpen(p)
|
||||
// A K3NG keyer reboots when the port opens (DTR is its reset line), so it is
|
||||
// given the long wait from the start rather than being failed once first.
|
||||
ver, err := hostOpen(p, cfg.Type == "k3ng")
|
||||
if err != nil {
|
||||
_ = p.Close()
|
||||
return fmt.Errorf("winkeyer: %s: %w", cfg.Port, err)
|
||||
|
||||
Reference in New Issue
Block a user