Skip to content

Commit 3a71cb3

Browse files
jgangemideadprogram
authored andcommitted
feat: add ResetAuto mode for automatic reset strategy detection
- rotate through classic DTR/RTS, USB-JTAG, and no-reset strategies - add ResetMode.String() method - extend hardReset with USB timing support
1 parent fef487b commit 3a71cb3

3 files changed

Lines changed: 53 additions & 0 deletions

File tree

pkg/espflasher/flasher.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,15 @@ func (f *Flasher) connect() error {
211211
}
212212
case ResetUSBJTAG:
213213
usbJTAGSerialReset(f.port)
214+
case ResetAuto:
215+
switch attempt % 3 {
216+
case 0:
217+
classicReset(f.port, defaultResetDelay)
218+
case 1:
219+
usbJTAGSerialReset(f.port)
220+
case 2:
221+
// No reset — device may already be in bootloader
222+
}
214223
}
215224
// ResetNoReset: skip reset entirely
216225

pkg/espflasher/flasher_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,28 @@ import (
88
"testing"
99
)
1010

11+
func TestResetModeString(t *testing.T) {
12+
tests := []struct {
13+
mode ResetMode
14+
want string
15+
}{
16+
{ResetDefault, "default"},
17+
{ResetNoReset, "no-reset"},
18+
{ResetUSBJTAG, "usb-jtag"},
19+
{ResetAuto, "auto"},
20+
{ResetMode(99), "unknown(99)"},
21+
}
22+
23+
for _, tt := range tests {
24+
t.Run(tt.want, func(t *testing.T) {
25+
got := tt.mode.String()
26+
if got != tt.want {
27+
t.Errorf("String() = %q, want %q", got, tt.want)
28+
}
29+
})
30+
}
31+
}
32+
1133
func TestDefaultOptions(t *testing.T) {
1234
opts := DefaultOptions()
1335

pkg/espflasher/reset.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package espflasher
22

33
import (
4+
"fmt"
45
"time"
56

67
"go.bug.st/serial"
@@ -19,6 +20,11 @@ const (
1920

2021
// ResetUSBJTAG uses the USB-JTAG/Serial reset sequence (ESP32-S3, ESP32-C3, etc.).
2122
ResetUSBJTAG
23+
24+
// ResetAuto tries multiple reset strategies in sequence.
25+
// First attempts DTR/RTS classic reset, then USB-JTAG, then no-signal.
26+
// Useful when the interface type is unknown.
27+
ResetAuto
2228
)
2329

2430
const (
@@ -112,3 +118,19 @@ func hardReset(port serial.Port, usesUSB bool) {
112118
port.SetRTS(false) //nolint:errcheck
113119
}
114120
}
121+
122+
// String returns the string representation of the ResetMode.
123+
func (r ResetMode) String() string {
124+
switch r {
125+
case ResetDefault:
126+
return "default"
127+
case ResetNoReset:
128+
return "no-reset"
129+
case ResetUSBJTAG:
130+
return "usb-jtag"
131+
case ResetAuto:
132+
return "auto"
133+
default:
134+
return fmt.Sprintf("unknown(%d)", int(r))
135+
}
136+
}

0 commit comments

Comments
 (0)