Skip to content

Commit a262ded

Browse files
committed
Experimental: optimized touch + wait
1 parent e5f4c95 commit a262ded

File tree

2 files changed

+110
-35
lines changed

2 files changed

+110
-35
lines changed

arduino/serialutils/serialutils.go

+75
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package serialutils
1717

1818
import (
19+
"fmt"
1920
"time"
2021

2122
"github.com/pkg/errors"
@@ -127,3 +128,77 @@ func WaitForNewSerialPort() (string, error) {
127128

128129
return "", nil
129130
}
131+
132+
// TouchAndWait FIXMEDOCS
133+
func TouchAndWait(portToTouch string, wait bool) (string, error) {
134+
getPortMap := func() (map[string]bool, error) {
135+
ports, err := serial.GetPortsList()
136+
if err != nil {
137+
return nil, errors.WithMessage(err, "listing serial ports")
138+
}
139+
res := map[string]bool{}
140+
for _, port := range ports {
141+
res[port] = true
142+
}
143+
return res, nil
144+
}
145+
146+
last, err := getPortMap()
147+
fmt.Println("LAST:", last)
148+
if err != nil {
149+
return "", err
150+
}
151+
152+
if portToTouch != "" {
153+
fmt.Println("TOUCH:", portToTouch)
154+
TouchSerialPortAt1200bps(portToTouch)
155+
}
156+
157+
if !wait {
158+
return "", nil
159+
}
160+
deadline := time.Now().Add(10 * time.Second)
161+
for time.Now().Before(deadline) {
162+
now, err := getPortMap()
163+
fmt.Println("NOW:", now)
164+
if err != nil {
165+
return "", err
166+
}
167+
hasNewPorts := false
168+
for p := range now {
169+
if !last[p] {
170+
hasNewPorts = true
171+
break
172+
}
173+
}
174+
175+
if hasNewPorts {
176+
fmt.Println("HAS NEW PORTS!")
177+
// on OS X, if the port is opened too quickly after it is detected,
178+
// a "Resource busy" error occurs, add a delay to workaround.
179+
// This apply to other platforms as well.
180+
time.Sleep(time.Second)
181+
182+
// Some boards have a glitch in the bootloader: some user experienced
183+
// the USB serial port appearing and disappearing rapidly before
184+
// settling.
185+
// This check ensure that the port is stable after one second.
186+
check, err := getPortMap()
187+
fmt.Println("CHECK:", check)
188+
if err != nil {
189+
return "", err
190+
}
191+
for p := range check {
192+
if !last[p] {
193+
fmt.Println("FOUND:", p)
194+
return p, nil // Found it!
195+
}
196+
}
197+
}
198+
199+
last = now
200+
time.Sleep(250 * time.Millisecond)
201+
}
202+
203+
return "", nil
204+
}

commands/upload/upload.go

+35-35
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import (
3636
properties "github.com/arduino/go-properties-orderedmap"
3737
"github.com/pkg/errors"
3838
"github.com/sirupsen/logrus"
39-
"go.bug.st/serial"
4039
)
4140

4241
// Upload FIXMEDOC
@@ -293,44 +292,45 @@ func runProgramAction(pm *packagemanager.PackageManager,
293292
// to set the board in bootloader mode
294293
actualPort := port
295294
if programmer == nil && !burnBootloader {
296-
// Perform reset via 1200bps touch if requested
297-
if uploadProperties.GetBoolean("upload.use_1200bps_touch") {
298-
if port == "" {
299-
outStream.Write([]byte(fmt.Sprintln("Skipping 1200-bps touch reset: no serial port selected!")))
300-
} else {
301-
ports, err := serial.GetPortsList()
302-
if err != nil {
303-
return fmt.Errorf("cannot get serial port list: %s", err)
304-
}
305-
for _, p := range ports {
306-
if p == port {
307-
if verbose {
308-
outStream.Write([]byte(fmt.Sprintf("Performing 1200-bps touch reset on serial port %s", p)))
309-
outStream.Write([]byte(fmt.Sprintln()))
310-
}
311-
logrus.Infof("Touching port %s at 1200bps", port)
312-
if err := serialutils.TouchSerialPortAt1200bps(p); err != nil {
313-
outStream.Write([]byte(fmt.Sprintf("Cannot perform port reset: %s", err)))
314-
outStream.Write([]byte(fmt.Sprintln()))
315-
}
316-
break
317-
}
318-
}
319-
}
295+
// Perform reset via 1200bps touch if requested and wait for upload port if requested.
296+
touch := uploadProperties.GetBoolean("upload.use_1200bps_touch")
297+
wait := uploadProperties.GetBoolean("upload.wait_for_upload_port")
298+
if touch && port == "" {
299+
outStream.Write([]byte(fmt.Sprintln("Skipping 1200-bps touch reset: no serial port selected!")))
320300
}
321301

322-
// Wait for upload port if requested
323-
if uploadProperties.GetBoolean("upload.wait_for_upload_port") {
324-
if verbose {
325-
outStream.Write([]byte(fmt.Sprintln("Waiting for upload port...")))
326-
}
327-
328-
actualPort, err = serialutils.WaitForNewSerialPortOrDefaultTo(actualPort)
329-
if err != nil {
330-
return errors.WithMessage(err, "detecting serial port")
302+
if newPort, err := serialutils.TouchAndWait(port, wait); err != nil {
303+
} else {
304+
if newPort != "" {
305+
actualPort = newPort
331306
}
332307
}
333-
}
308+
// ports, err := serial.GetPortsList()
309+
// for _, p := range ports {
310+
// if p == port {
311+
// if verbose {
312+
// outStream.Write([]byte(fmt.Sprintf("Performing 1200-bps touch reset on serial port %s", p)))
313+
// outStream.Write([]byte(fmt.Sprintln()))
314+
// }
315+
// logrus.Infof("Touching port %s at 1200bps", port)
316+
// if err := serialutils.TouchSerialPortAt1200bps(p); err != nil {
317+
// outStream.Write([]byte(fmt.Sprintf("Cannot perform port reset: %s", err)))
318+
// outStream.Write([]byte(fmt.Sprintln()))
319+
// }
320+
// break
321+
// }
322+
// }
323+
}
324+
325+
// Wait for upload port if requested
326+
// if verbose {
327+
// outStream.Write([]byte(fmt.Sprintln("Waiting for upload port...")))
328+
// }
329+
330+
// actualPort, err = serialutils.WaitForNewSerialPortOrDefaultTo(actualPort)
331+
// if err != nil {
332+
// return errors.WithMessage(err, "detecting serial port")
333+
// }
334334

335335
if port != "" {
336336
// Set serial port property

0 commit comments

Comments
 (0)